simplified structure of store builders

This commit is contained in:
Sebastian Sdorra
2020-04-28 09:47:16 +02:00
parent 5140bdf6b0
commit dbc97d8993
11 changed files with 223 additions and 345 deletions

View File

@@ -24,8 +24,6 @@
package sonia.scm.store;
import sonia.scm.repository.Repository;
/**
* The BlobStoreFactory can be used to create a new or get an existing {@link BlobStore}s.
* <br>
@@ -66,66 +64,7 @@ public interface BlobStoreFactory {
* @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 String repositoryId;
private final BlobStoreFactory factory;
FloatingStoreParameters(BlobStoreFactory factory) {
this.factory = factory;
}
@Override
public String getName() {
return name;
}
@Override
public String getRepositoryId() {
return repositoryId;
}
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.repositoryId = repository.getId();
return this;
}
/**
* 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 repositoryId The id of the optional repository for the {@link BlobStore}.
* @return Floating API to finish the call.
*/
public FloatingStoreParameters.Builder forRepository(String repositoryId) {
FloatingStoreParameters.this.repositoryId = repositoryId;
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);
}
default StoreParametersBuilder<BlobStore> withName(String name) {
return new StoreParametersBuilder<>(name, this::getStore);
}
}

View File

@@ -24,8 +24,6 @@
package sonia.scm.store;
import sonia.scm.repository.Repository;
/**
* The ConfigurationEntryStoreFactory can be used to create new or get existing {@link ConfigurationEntryStore}s.
* <br>
@@ -72,67 +70,7 @@ public interface ConfigurationEntryStoreFactory {
* @return Floating API to set the name and either specify a repository or directly build a global
* {@link ConfigurationEntryStore}.
*/
default <T> TypedFloatingConfigurationEntryStoreParameters<T>.Builder withType(Class<T> type) {
return new TypedFloatingConfigurationEntryStoreParameters<T>(this).new Builder(type);
}
}
final class TypedFloatingConfigurationEntryStoreParameters<T> {
private final TypedStoreParametersImpl<T> parameters = new TypedStoreParametersImpl<>();
private final ConfigurationEntryStoreFactory factory;
TypedFloatingConfigurationEntryStoreParameters(ConfigurationEntryStoreFactory factory) {
this.factory = factory;
}
public class Builder {
Builder(Class<T> 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.setRepositoryId(repository.getId());
return this;
}
/**
* 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 repositoryId The id of the optional repository for the {@link ConfigurationEntryStore}.
* @return Floating API to finish the call.
*/
public OptionalRepositoryBuilder forRepository(String repositoryId) {
parameters.setRepositoryId(repositoryId);
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<T> build(){
return factory.getStore(parameters);
}
default <T> TypedStoreParametersBuilder<T, ConfigurationEntryStore<T>> withType(Class<T> type) {
return new TypedStoreParametersBuilder<>(type, this::getStore);
}
}

View File

@@ -25,8 +25,6 @@
package sonia.scm.store;
import sonia.scm.repository.Repository;
/**
* The ConfigurationStoreFactory can be used to create new or get existing {@link ConfigurationStore} objects.
* <br>
@@ -72,67 +70,7 @@ public interface ConfigurationStoreFactory {
* @return Floating API to set the name and either specify a repository or directly build a global
* {@link ConfigurationStore}.
*/
default <T> TypedFloatingConfigurationStoreParameters<T>.Builder withType(Class<T> type) {
return new TypedFloatingConfigurationStoreParameters<T>(this).new Builder(type);
}
}
final class TypedFloatingConfigurationStoreParameters<T> {
private final TypedStoreParametersImpl<T> parameters = new TypedStoreParametersImpl<>();
private final ConfigurationStoreFactory factory;
TypedFloatingConfigurationStoreParameters(ConfigurationStoreFactory factory) {
this.factory = factory;
}
public class Builder {
Builder(Class<T> 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.setRepositoryId(repository.getId());
return this;
}
/**
* 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 repositoryId The id of the optional repository for the {@link ConfigurationStore}.
* @return Floating API to finish the call.
*/
public OptionalRepositoryBuilder forRepository(String repositoryId) {
parameters.setRepositoryId(repositoryId);
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<T> build(){
return factory.getStore(parameters);
}
default <T> TypedStoreParametersBuilder<T,ConfigurationStore<T>> withType(Class<T> type) {
return new TypedStoreParametersBuilder<>(type, this::getStore);
}
}

View File

@@ -24,8 +24,6 @@
package sonia.scm.store;
import sonia.scm.repository.Repository;
/**
* The DataStoreFactory can be used to create new or get existing {@link DataStore}s.
* <br>
@@ -69,67 +67,7 @@ public interface DataStoreFactory {
* @return Floating API to set the name and either specify a repository or directly build a global
* {@link DataStore}.
*/
default <T> TypedFloatingDataStoreParameters<T>.Builder withType(Class<T> type) {
return new TypedFloatingDataStoreParameters<T>(this).new Builder(type);
}
}
final class TypedFloatingDataStoreParameters<T> {
private final TypedStoreParametersImpl<T> parameters = new TypedStoreParametersImpl<>();
private final DataStoreFactory factory;
TypedFloatingDataStoreParameters(DataStoreFactory factory) {
this.factory = factory;
}
public class Builder {
Builder(Class<T> 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.setRepositoryId(repository.getId());
return this;
}
/**
* 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 repositoryId The id of the optional repository for the {@link DataStore}.
* @return Floating API to finish the call.
*/
public OptionalRepositoryBuilder forRepository(String repositoryId) {
parameters.setRepositoryId(repositoryId);
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<T> build(){
return factory.getStore(parameters);
}
default <T> TypedStoreParametersBuilder<T, DataStore<T>> withType(Class<T> type) {
return new TypedStoreParametersBuilder<>(type, this::getStore);
}
}

View File

@@ -24,8 +24,6 @@
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.
*

View File

@@ -0,0 +1,90 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.store;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import sonia.scm.repository.Repository;
import java.util.function.Function;
/**
* Builder for {@link StoreParameters}.
*
* @param <S> type of store
*/
public final class StoreParametersBuilder<S> {
private final StoreParametersImpl parameters;
private final Function<StoreParameters, S> factory;
StoreParametersBuilder(String name, Function<StoreParameters, S> factory) {
this.parameters = new StoreParametersImpl(name);
this.factory = factory;
}
@Getter
@Setter(AccessLevel.PRIVATE)
@RequiredArgsConstructor
private static class StoreParametersImpl implements StoreParameters {
private final String name;
private String repositoryId;
}
/**
* Use this to create or get a store for a specific repository. This step is optional. If you want to
* have a global store, omit this.
*
* @param repository The optional repository for the store.
* @return Floating API to finish the call.
*/
public StoreParametersBuilder<S> forRepository(Repository repository) {
parameters.repositoryId = repository.getId();
return this;
}
/**
* Use this to create or get a store for a specific repository. This step is optional. If you want to
* have a global store, omit this.
*
* @param repositoryId The id of the optional repository for the store.
* @return Floating API to finish the call.
*/
public StoreParametersBuilder<S> forRepository(String repositoryId) {
parameters.repositoryId = repositoryId;
return this;
}
/**
* Creates or gets the store with the given name and (if specified) the given repository. If no
* repository is given, the store will be global.
*/
public S build() {
return factory.apply(parameters);
}
}

View File

@@ -24,8 +24,6 @@
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.
@@ -33,11 +31,8 @@ import sonia.scm.repository.Repository;
* @author Mohamed Karray
* @since 2.0.0
*/
public interface TypedStoreParameters<T> {
public interface TypedStoreParameters<T> extends StoreParameters {
Class<T> getType();
String getName();
String getRepositoryId();
}

View File

@@ -0,0 +1,102 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.store;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import sonia.scm.repository.Repository;
import java.util.function.Function;
/**
* Builder for {@link TypedStoreParameters}.
*
* @param <T> type of data
* @param <S> type of store
*/
public final class TypedStoreParametersBuilder<T,S> {
private final TypedStoreParametersImpl<T> parameters;
private final Function<TypedStoreParameters<T>, S> factory;
TypedStoreParametersBuilder(Class<T> type, Function<TypedStoreParameters<T>, S> factory) {
this.factory = factory;
this.parameters = new TypedStoreParametersImpl<>(type);
}
/**
* Use this to set the name for the store.
* @param name The name for the store.
* @return Floating API to either specify a repository or directly build a global store.
*/
public OptionalRepositoryBuilder withName(String name) {
parameters.setName(name);
return new OptionalRepositoryBuilder();
}
@Getter
@Setter(AccessLevel.PRIVATE)
@RequiredArgsConstructor
private static class TypedStoreParametersImpl<T> implements TypedStoreParameters<T> {
private final Class<T> type;
private String name;
private String repositoryId;
}
public class OptionalRepositoryBuilder {
/**
* Use this to create or get a store for a specific repository. This step is optional. If you
* want to have a global store, omit this.
* @param repository The optional repository for the store.
* @return Floating API to finish the call.
*/
public OptionalRepositoryBuilder forRepository(Repository repository) {
parameters.setRepositoryId(repository.getId());
return this;
}
/**
* Use this to create or get a store for a specific repository. This step is optional. If you
* want to have a global store, omit this.
* @param repositoryId The id of the optional repository for the store.
* @return Floating API to finish the call.
*/
public OptionalRepositoryBuilder forRepository(String repositoryId) {
parameters.setRepositoryId(repositoryId);
return this;
}
/**
* Creates or gets the store with the given name and (if specified) the given repository. If no
* repository is given, the store will be global.
*/
public S build(){
return factory.apply(parameters);
}
}
}

View File

@@ -1,58 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.store;
class TypedStoreParametersImpl<T> implements TypedStoreParameters<T> {
private Class<T> type;
private String name;
private String repositoryId;
@Override
public Class<T> getType() {
return type;
}
void setType(Class<T> type) {
this.type = type;
}
@Override
public String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
@Override
public String getRepositoryId() {
return repositoryId;
}
void setRepositoryId(String repositoryId) {
this.repositoryId = repositoryId;
}
}

View File

@@ -52,7 +52,7 @@ public class JAXBDataStoreTest extends DataStoreTestBase {
}
@Override
protected DataStore getDataStore(Class type, Repository repository) {
protected <T> DataStore<T> getDataStore(Class<T> type, Repository repository) {
return createDataStoreFactory()
.withType(type)
.withName("test")
@@ -61,7 +61,7 @@ public class JAXBDataStoreTest extends DataStoreTestBase {
}
@Override
protected DataStore getDataStore(Class type) {
protected <T> DataStore<T> getDataStore(Class<T> type) {
return createDataStoreFactory()
.withType(type)
.withName("test")

View File

@@ -27,7 +27,6 @@ package sonia.scm.store;
import sonia.scm.repository.Repository;
/**
*
* @author Sebastian Sdorra
*/
public abstract class ConfigurationEntryStoreTestBase extends KeyValueStoreTestBase {
@@ -35,14 +34,13 @@ public abstract class ConfigurationEntryStoreTestBase extends KeyValueStoreTestB
/**
* Method description
*
*
* @return
*/
protected abstract ConfigurationEntryStoreFactory createConfigurationStoreFactory();
//~--- get methods ----------------------------------------------------------
@Override
protected ConfigurationEntryStore getDataStore(Class type) {
protected <T> ConfigurationEntryStore<T> getDataStore(Class<T> type) {
return this.createConfigurationStoreFactory()
.withType(type)
.withName(storeName)
@@ -50,7 +48,7 @@ public abstract class ConfigurationEntryStoreTestBase extends KeyValueStoreTestB
}
@Override
protected ConfigurationEntryStore getDataStore(Class type, Repository repository) {
protected <T> ConfigurationEntryStore<T> getDataStore(Class<T> type, Repository repository) {
return this.createConfigurationStoreFactory()
.withType(type)
.withName(repoStoreName)