builderConsumer) {
+ Builder builder = newOptionsBuilder();
+ builderConsumer.accept(builder);
+ return builder.build();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || getClass() != o.getClass()) return false;
+ DataLoaderOptions that = (DataLoaderOptions) o;
+ return batchingEnabled == that.batchingEnabled
+ && cachingEnabled == that.cachingEnabled
+ && cachingExceptionsEnabled == that.cachingExceptionsEnabled
+ && maxBatchSize == that.maxBatchSize
+ && Objects.equals(cacheKeyFunction, that.cacheKeyFunction) &&
+ Objects.equals(cacheMap, that.cacheMap) &&
+ Objects.equals(valueCache, that.valueCache) &&
+ Objects.equals(statisticsCollector, that.statisticsCollector) &&
+ Objects.equals(environmentProvider, that.environmentProvider) &&
+ Objects.equals(valueCacheOptions, that.valueCacheOptions) &&
+ Objects.equals(batchLoaderScheduler, that.batchLoaderScheduler);
+ }
+
+
/**
* Option that determines whether to use batching (the default), or not.
*
@@ -103,12 +169,10 @@ public boolean batchingEnabled() {
* Sets the option that determines whether batch loading is enabled.
*
* @param batchingEnabled {@code true} to enable batch loading, {@code false} otherwise
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setBatchingEnabled(boolean batchingEnabled) {
- this.batchingEnabled = batchingEnabled;
- return this;
+ return builder().setBatchingEnabled(batchingEnabled).build();
}
/**
@@ -124,17 +188,15 @@ public boolean cachingEnabled() {
* Sets the option that determines whether caching is enabled.
*
* @param cachingEnabled {@code true} to enable caching, {@code false} otherwise
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setCachingEnabled(boolean cachingEnabled) {
- this.cachingEnabled = cachingEnabled;
- return this;
+ return builder().setCachingEnabled(cachingEnabled).build();
}
/**
* Option that determines whether to cache exceptional values (the default), or not.
- *
+ *
* For short-lived caches (that is request caches) it makes sense to cache exceptions since
* it's likely the key is still poisoned. However, if you have long-lived caches, then it may make
* sense to set this to false since the downstream system may have recovered from its failure
@@ -150,12 +212,10 @@ public boolean cachingExceptionsEnabled() {
* Sets the option that determines whether exceptional values are cache enabled.
*
* @param cachingExceptionsEnabled {@code true} to enable caching exceptional values, {@code false} otherwise
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setCachingExceptionsEnabled(boolean cachingExceptionsEnabled) {
- this.cachingExceptionsEnabled = cachingExceptionsEnabled;
- return this;
+ return builder().setCachingExceptionsEnabled(cachingExceptionsEnabled).build();
}
/**
@@ -173,12 +233,10 @@ public Optional cacheKeyFunction() {
* Sets the function to use for creating the cache key, if caching is enabled.
*
* @param cacheKeyFunction the cache key function to use
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setCacheKeyFunction(CacheKey> cacheKeyFunction) {
- this.cacheKeyFunction = cacheKeyFunction;
- return this;
+ return builder().setCacheKeyFunction(cacheKeyFunction).build();
}
/**
@@ -196,12 +254,10 @@ public DataLoaderOptions setCacheKeyFunction(CacheKey> cacheKeyFunction) {
* Sets the cache map implementation to use for caching, if caching is enabled.
*
* @param cacheMap the cache map instance
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setCacheMap(CacheMap, ?> cacheMap) {
- this.cacheMap = cacheMap;
- return this;
+ return builder().setCacheMap(cacheMap).build();
}
/**
@@ -219,12 +275,10 @@ public int maxBatchSize() {
* before they are split into multiple class
*
* @param maxBatchSize the maximum batch size
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setMaxBatchSize(int maxBatchSize) {
- this.maxBatchSize = maxBatchSize;
- return this;
+ return builder().setMaxBatchSize(maxBatchSize).build();
}
/**
@@ -240,12 +294,10 @@ public StatisticsCollector getStatisticsCollector() {
* a common value
*
* @param statisticsCollector the statistics collector to use
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setStatisticsCollector(Supplier statisticsCollector) {
- this.statisticsCollector = nonNull(statisticsCollector);
- return this;
+ return builder().setStatisticsCollector(nonNull(statisticsCollector)).build();
}
/**
@@ -259,12 +311,10 @@ public BatchLoaderContextProvider getBatchLoaderContextProvider() {
* Sets the batch loader environment provider that will be used to give context to batch load functions
*
* @param contextProvider the batch loader context provider
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setBatchLoaderContextProvider(BatchLoaderContextProvider contextProvider) {
- this.environmentProvider = nonNull(contextProvider);
- return this;
+ return builder().setBatchLoaderContextProvider(nonNull(contextProvider)).build();
}
/**
@@ -282,12 +332,10 @@ public DataLoaderOptions setBatchLoaderContextProvider(BatchLoaderContextProvide
* Sets the value cache implementation to use for caching values, if caching is enabled.
*
* @param valueCache the value cache instance
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setValueCache(ValueCache, ?> valueCache) {
- this.valueCache = valueCache;
- return this;
+ return builder().setValueCache(valueCache).build();
}
/**
@@ -301,12 +349,10 @@ public ValueCacheOptions getValueCacheOptions() {
* Sets the {@link ValueCacheOptions} that control how the {@link ValueCache} will be used
*
* @param valueCacheOptions the value cache options
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setValueCacheOptions(ValueCacheOptions valueCacheOptions) {
- this.valueCacheOptions = Assertions.nonNull(valueCacheOptions);
- return this;
+ return builder().setValueCacheOptions(nonNull(valueCacheOptions)).build();
}
/**
@@ -321,11 +367,105 @@ public BatchLoaderScheduler getBatchLoaderScheduler() {
* to some future time.
*
* @param batchLoaderScheduler the scheduler
- *
* @return the data loader options for fluent coding
*/
public DataLoaderOptions setBatchLoaderScheduler(BatchLoaderScheduler batchLoaderScheduler) {
- this.batchLoaderScheduler = batchLoaderScheduler;
- return this;
+ return builder().setBatchLoaderScheduler(batchLoaderScheduler).build();
+ }
+
+ private Builder builder() {
+ return new Builder(this);
+ }
+
+ public static class Builder {
+ private boolean batchingEnabled;
+ private boolean cachingEnabled;
+ private boolean cachingExceptionsEnabled;
+ private CacheKey> cacheKeyFunction;
+ private CacheMap, ?> cacheMap;
+ private ValueCache, ?> valueCache;
+ private int maxBatchSize;
+ private Supplier statisticsCollector;
+ private BatchLoaderContextProvider environmentProvider;
+ private ValueCacheOptions valueCacheOptions;
+ private BatchLoaderScheduler batchLoaderScheduler;
+
+ public Builder() {
+ this(new DataLoaderOptions()); // use the defaults of the DataLoaderOptions for this builder
+ }
+
+ Builder(DataLoaderOptions other) {
+ this.batchingEnabled = other.batchingEnabled;
+ this.cachingEnabled = other.cachingEnabled;
+ this.cachingExceptionsEnabled = other.cachingExceptionsEnabled;
+ this.cacheKeyFunction = other.cacheKeyFunction;
+ this.cacheMap = other.cacheMap;
+ this.valueCache = other.valueCache;
+ this.maxBatchSize = other.maxBatchSize;
+ this.statisticsCollector = other.statisticsCollector;
+ this.environmentProvider = other.environmentProvider;
+ this.valueCacheOptions = other.valueCacheOptions;
+ this.batchLoaderScheduler = other.batchLoaderScheduler;
+ }
+
+ public Builder setBatchingEnabled(boolean batchingEnabled) {
+ this.batchingEnabled = batchingEnabled;
+ return this;
+ }
+
+ public Builder setCachingEnabled(boolean cachingEnabled) {
+ this.cachingEnabled = cachingEnabled;
+ return this;
+ }
+
+ public Builder setCachingExceptionsEnabled(boolean cachingExceptionsEnabled) {
+ this.cachingExceptionsEnabled = cachingExceptionsEnabled;
+ return this;
+ }
+
+ public Builder setCacheKeyFunction(CacheKey> cacheKeyFunction) {
+ this.cacheKeyFunction = cacheKeyFunction;
+ return this;
+ }
+
+ public Builder setCacheMap(CacheMap, ?> cacheMap) {
+ this.cacheMap = cacheMap;
+ return this;
+ }
+
+ public Builder setValueCache(ValueCache, ?> valueCache) {
+ this.valueCache = valueCache;
+ return this;
+ }
+
+ public Builder setMaxBatchSize(int maxBatchSize) {
+ this.maxBatchSize = maxBatchSize;
+ return this;
+ }
+
+ public Builder setStatisticsCollector(Supplier statisticsCollector) {
+ this.statisticsCollector = statisticsCollector;
+ return this;
+ }
+
+ public Builder setBatchLoaderContextProvider(BatchLoaderContextProvider environmentProvider) {
+ this.environmentProvider = environmentProvider;
+ return this;
+ }
+
+ public Builder setValueCacheOptions(ValueCacheOptions valueCacheOptions) {
+ this.valueCacheOptions = valueCacheOptions;
+ return this;
+ }
+
+ public Builder setBatchLoaderScheduler(BatchLoaderScheduler batchLoaderScheduler) {
+ this.batchLoaderScheduler = batchLoaderScheduler;
+ return this;
+ }
+
+ public DataLoaderOptions build() {
+ return new DataLoaderOptions(this);
+ }
+
}
}
diff --git a/src/test/java/org/dataloader/DataLoaderOptionsTest.java b/src/test/java/org/dataloader/DataLoaderOptionsTest.java
new file mode 100644
index 0000000..f6e06e8
--- /dev/null
+++ b/src/test/java/org/dataloader/DataLoaderOptionsTest.java
@@ -0,0 +1,187 @@
+package org.dataloader;
+
+import org.dataloader.impl.DefaultCacheMap;
+import org.dataloader.impl.NoOpValueCache;
+import org.dataloader.scheduler.BatchLoaderScheduler;
+import org.dataloader.stats.NoOpStatisticsCollector;
+import org.dataloader.stats.StatisticsCollector;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletionStage;
+import java.util.function.Supplier;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@SuppressWarnings("OptionalGetWithoutIsPresent")
+class DataLoaderOptionsTest {
+
+ DataLoaderOptions optionsDefault = new DataLoaderOptions();
+
+ @Test
+ void canCreateDefaultOptions() {
+
+ assertThat(optionsDefault.batchingEnabled(), equalTo(true));
+ assertThat(optionsDefault.cachingEnabled(), equalTo(true));
+ assertThat(optionsDefault.cachingExceptionsEnabled(), equalTo(true));
+ assertThat(optionsDefault.maxBatchSize(), equalTo(-1));
+ assertThat(optionsDefault.getBatchLoaderScheduler(), equalTo(null));
+
+ DataLoaderOptions builtOptions = DataLoaderOptions.newOptionsBuilder().build();
+ assertThat(builtOptions, equalTo(optionsDefault));
+ assertThat(builtOptions == optionsDefault, equalTo(false));
+
+ DataLoaderOptions transformedOptions = optionsDefault.transform(builder -> {
+ });
+ assertThat(transformedOptions, equalTo(optionsDefault));
+ assertThat(transformedOptions == optionsDefault, equalTo(false));
+ }
+
+ @Test
+ void canCopyOk() {
+ DataLoaderOptions optionsNext = new DataLoaderOptions(optionsDefault);
+ assertThat(optionsNext, equalTo(optionsDefault));
+ assertThat(optionsNext == optionsDefault, equalTo(false));
+
+ optionsNext = DataLoaderOptions.newDataLoaderOptions(optionsDefault).build();
+ assertThat(optionsNext, equalTo(optionsDefault));
+ assertThat(optionsNext == optionsDefault, equalTo(false));
+ }
+
+ BatchLoaderScheduler testBatchLoaderScheduler = new BatchLoaderScheduler() {
+ @Override
+ public CompletionStage> scheduleBatchLoader(ScheduledBatchLoaderCall scheduledCall, List keys, BatchLoaderEnvironment environment) {
+ return null;
+ }
+
+ @Override
+ public CompletionStage