1717package org .dataloader ;
1818
1919import org .dataloader .annotations .PublicApi ;
20- import org .dataloader .impl .Assertions ;
2120import org .dataloader .scheduler .BatchLoaderScheduler ;
2221import org .dataloader .stats .NoOpStatisticsCollector ;
2322import org .dataloader .stats .StatisticsCollector ;
2423
24+ import java .util .Objects ;
2525import java .util .Optional ;
26+ import java .util .function .Consumer ;
2627import java .util .function .Supplier ;
2728
2829import static org .dataloader .impl .Assertions .nonNull ;
2930
3031/**
31- * Configuration options for {@link DataLoader} instances.
32+ * Configuration options for {@link DataLoader} instances. This is an immutable class so each time
33+ * you change a value it returns a new object.
3234 *
3335 * @author <a href="https://github.com/aschrijver/">Arnold Schrijver</a>
3436 */
3537@ PublicApi
3638public class DataLoaderOptions {
3739
3840 private static final BatchLoaderContextProvider NULL_PROVIDER = () -> null ;
39-
40- private boolean batchingEnabled ;
41- private boolean cachingEnabled ;
42- private boolean cachingExceptionsEnabled ;
43- private CacheKey <?> cacheKeyFunction ;
44- private CacheMap <?, ?> cacheMap ;
45- private ValueCache <?, ?> valueCache ;
46- private int maxBatchSize ;
47- private Supplier <StatisticsCollector > statisticsCollector ;
48- private BatchLoaderContextProvider environmentProvider ;
49- private ValueCacheOptions valueCacheOptions ;
50- private BatchLoaderScheduler batchLoaderScheduler ;
41+ private static final Supplier <StatisticsCollector > NOOP_COLLECTOR = NoOpStatisticsCollector ::new ;
42+ private static final ValueCacheOptions DEFAULT_VALUE_CACHE_OPTIONS = ValueCacheOptions .newOptions ();
43+
44+ private final boolean batchingEnabled ;
45+ private final boolean cachingEnabled ;
46+ private final boolean cachingExceptionsEnabled ;
47+ private final CacheKey <?> cacheKeyFunction ;
48+ private final CacheMap <?, ?> cacheMap ;
49+ private final ValueCache <?, ?> valueCache ;
50+ private final int maxBatchSize ;
51+ private final Supplier <StatisticsCollector > statisticsCollector ;
52+ private final BatchLoaderContextProvider environmentProvider ;
53+ private final ValueCacheOptions valueCacheOptions ;
54+ private final BatchLoaderScheduler batchLoaderScheduler ;
5155
5256 /**
5357 * Creates a new data loader options with default settings.
@@ -56,13 +60,30 @@ public DataLoaderOptions() {
5660 batchingEnabled = true ;
5761 cachingEnabled = true ;
5862 cachingExceptionsEnabled = true ;
63+ cacheKeyFunction = null ;
64+ cacheMap = null ;
65+ valueCache = null ;
5966 maxBatchSize = -1 ;
60- statisticsCollector = NoOpStatisticsCollector :: new ;
67+ statisticsCollector = NOOP_COLLECTOR ;
6168 environmentProvider = NULL_PROVIDER ;
62- valueCacheOptions = ValueCacheOptions . newOptions () ;
69+ valueCacheOptions = DEFAULT_VALUE_CACHE_OPTIONS ;
6370 batchLoaderScheduler = null ;
6471 }
6572
73+ private DataLoaderOptions (Builder builder ) {
74+ this .batchingEnabled = builder .batchingEnabled ;
75+ this .cachingEnabled = builder .cachingEnabled ;
76+ this .cachingExceptionsEnabled = builder .cachingExceptionsEnabled ;
77+ this .cacheKeyFunction = builder .cacheKeyFunction ;
78+ this .cacheMap = builder .cacheMap ;
79+ this .valueCache = builder .valueCache ;
80+ this .maxBatchSize = builder .maxBatchSize ;
81+ this .statisticsCollector = builder .statisticsCollector ;
82+ this .environmentProvider = builder .environmentProvider ;
83+ this .valueCacheOptions = builder .valueCacheOptions ;
84+ this .batchLoaderScheduler = builder .batchLoaderScheduler ;
85+ }
86+
6687 /**
6788 * Clones the provided data loader options.
6889 *
@@ -90,6 +111,51 @@ public static DataLoaderOptions newOptions() {
90111 return new DataLoaderOptions ();
91112 }
92113
114+ /**
115+ * @return a new default data loader options {@link Builder} that you can then customize
116+ */
117+ public static DataLoaderOptions .Builder newOptionsBuilder () {
118+ return new DataLoaderOptions .Builder ();
119+ }
120+
121+ /**
122+ * @param otherOptions the options to copy
123+ * @return a new default data loader options {@link Builder} from the specified one that you can then customize
124+ */
125+ public static DataLoaderOptions .Builder newDataLoaderOptions (DataLoaderOptions otherOptions ) {
126+ return new DataLoaderOptions .Builder (otherOptions );
127+ }
128+
129+ /**
130+ * Will transform the current options in to a builder ands allow you to build a new set of options
131+ *
132+ * @param builderConsumer the consumer of a builder that has this objects starting values
133+ * @return a new {@link DataLoaderOptions} object
134+ */
135+ public DataLoaderOptions transform (Consumer <Builder > builderConsumer ) {
136+ Builder builder = newOptionsBuilder ();
137+ builderConsumer .accept (builder );
138+ return builder .build ();
139+ }
140+
141+ @ Override
142+ public boolean equals (Object o ) {
143+ if (o == null || getClass () != o .getClass ()) return false ;
144+ DataLoaderOptions that = (DataLoaderOptions ) o ;
145+ return batchingEnabled == that .batchingEnabled
146+ && cachingEnabled == that .cachingEnabled
147+ && cachingExceptionsEnabled == that .cachingExceptionsEnabled
148+ && maxBatchSize == that .maxBatchSize
149+ && Objects .equals (cacheKeyFunction , that .cacheKeyFunction ) &&
150+ Objects .equals (cacheMap , that .cacheMap ) &&
151+ Objects .equals (valueCache , that .valueCache ) &&
152+ Objects .equals (statisticsCollector , that .statisticsCollector ) &&
153+ Objects .equals (environmentProvider , that .environmentProvider ) &&
154+ Objects .equals (valueCacheOptions , that .valueCacheOptions ) &&
155+ Objects .equals (batchLoaderScheduler , that .batchLoaderScheduler );
156+ }
157+
158+
93159 /**
94160 * Option that determines whether to use batching (the default), or not.
95161 *
@@ -103,12 +169,10 @@ public boolean batchingEnabled() {
103169 * Sets the option that determines whether batch loading is enabled.
104170 *
105171 * @param batchingEnabled {@code true} to enable batch loading, {@code false} otherwise
106- *
107172 * @return the data loader options for fluent coding
108173 */
109174 public DataLoaderOptions setBatchingEnabled (boolean batchingEnabled ) {
110- this .batchingEnabled = batchingEnabled ;
111- return this ;
175+ return builder ().setBatchingEnabled (batchingEnabled ).build ();
112176 }
113177
114178 /**
@@ -124,17 +188,15 @@ public boolean cachingEnabled() {
124188 * Sets the option that determines whether caching is enabled.
125189 *
126190 * @param cachingEnabled {@code true} to enable caching, {@code false} otherwise
127- *
128191 * @return the data loader options for fluent coding
129192 */
130193 public DataLoaderOptions setCachingEnabled (boolean cachingEnabled ) {
131- this .cachingEnabled = cachingEnabled ;
132- return this ;
194+ return builder ().setCachingEnabled (cachingEnabled ).build ();
133195 }
134196
135197 /**
136198 * Option that determines whether to cache exceptional values (the default), or not.
137- *
199+ * <p>
138200 * For short-lived caches (that is request caches) it makes sense to cache exceptions since
139201 * it's likely the key is still poisoned. However, if you have long-lived caches, then it may make
140202 * sense to set this to false since the downstream system may have recovered from its failure
@@ -150,12 +212,10 @@ public boolean cachingExceptionsEnabled() {
150212 * Sets the option that determines whether exceptional values are cache enabled.
151213 *
152214 * @param cachingExceptionsEnabled {@code true} to enable caching exceptional values, {@code false} otherwise
153- *
154215 * @return the data loader options for fluent coding
155216 */
156217 public DataLoaderOptions setCachingExceptionsEnabled (boolean cachingExceptionsEnabled ) {
157- this .cachingExceptionsEnabled = cachingExceptionsEnabled ;
158- return this ;
218+ return builder ().setCachingExceptionsEnabled (cachingExceptionsEnabled ).build ();
159219 }
160220
161221 /**
@@ -173,12 +233,10 @@ public Optional<CacheKey> cacheKeyFunction() {
173233 * Sets the function to use for creating the cache key, if caching is enabled.
174234 *
175235 * @param cacheKeyFunction the cache key function to use
176- *
177236 * @return the data loader options for fluent coding
178237 */
179238 public DataLoaderOptions setCacheKeyFunction (CacheKey <?> cacheKeyFunction ) {
180- this .cacheKeyFunction = cacheKeyFunction ;
181- return this ;
239+ return builder ().setCacheKeyFunction (cacheKeyFunction ).build ();
182240 }
183241
184242 /**
@@ -196,12 +254,10 @@ public DataLoaderOptions setCacheKeyFunction(CacheKey<?> cacheKeyFunction) {
196254 * Sets the cache map implementation to use for caching, if caching is enabled.
197255 *
198256 * @param cacheMap the cache map instance
199- *
200257 * @return the data loader options for fluent coding
201258 */
202259 public DataLoaderOptions setCacheMap (CacheMap <?, ?> cacheMap ) {
203- this .cacheMap = cacheMap ;
204- return this ;
260+ return builder ().setCacheMap (cacheMap ).build ();
205261 }
206262
207263 /**
@@ -219,12 +275,10 @@ public int maxBatchSize() {
219275 * before they are split into multiple class
220276 *
221277 * @param maxBatchSize the maximum batch size
222- *
223278 * @return the data loader options for fluent coding
224279 */
225280 public DataLoaderOptions setMaxBatchSize (int maxBatchSize ) {
226- this .maxBatchSize = maxBatchSize ;
227- return this ;
281+ return builder ().setMaxBatchSize (maxBatchSize ).build ();
228282 }
229283
230284 /**
@@ -240,12 +294,10 @@ public StatisticsCollector getStatisticsCollector() {
240294 * a common value
241295 *
242296 * @param statisticsCollector the statistics collector to use
243- *
244297 * @return the data loader options for fluent coding
245298 */
246299 public DataLoaderOptions setStatisticsCollector (Supplier <StatisticsCollector > statisticsCollector ) {
247- this .statisticsCollector = nonNull (statisticsCollector );
248- return this ;
300+ return builder ().setStatisticsCollector (nonNull (statisticsCollector )).build ();
249301 }
250302
251303 /**
@@ -259,12 +311,10 @@ public BatchLoaderContextProvider getBatchLoaderContextProvider() {
259311 * Sets the batch loader environment provider that will be used to give context to batch load functions
260312 *
261313 * @param contextProvider the batch loader context provider
262- *
263314 * @return the data loader options for fluent coding
264315 */
265316 public DataLoaderOptions setBatchLoaderContextProvider (BatchLoaderContextProvider contextProvider ) {
266- this .environmentProvider = nonNull (contextProvider );
267- return this ;
317+ return builder ().setBatchLoaderContextProvider (nonNull (contextProvider )).build ();
268318 }
269319
270320 /**
@@ -282,12 +332,10 @@ public DataLoaderOptions setBatchLoaderContextProvider(BatchLoaderContextProvide
282332 * Sets the value cache implementation to use for caching values, if caching is enabled.
283333 *
284334 * @param valueCache the value cache instance
285- *
286335 * @return the data loader options for fluent coding
287336 */
288337 public DataLoaderOptions setValueCache (ValueCache <?, ?> valueCache ) {
289- this .valueCache = valueCache ;
290- return this ;
338+ return builder ().setValueCache (valueCache ).build ();
291339 }
292340
293341 /**
@@ -301,12 +349,10 @@ public ValueCacheOptions getValueCacheOptions() {
301349 * Sets the {@link ValueCacheOptions} that control how the {@link ValueCache} will be used
302350 *
303351 * @param valueCacheOptions the value cache options
304- *
305352 * @return the data loader options for fluent coding
306353 */
307354 public DataLoaderOptions setValueCacheOptions (ValueCacheOptions valueCacheOptions ) {
308- this .valueCacheOptions = Assertions .nonNull (valueCacheOptions );
309- return this ;
355+ return builder ().setValueCacheOptions (nonNull (valueCacheOptions )).build ();
310356 }
311357
312358 /**
@@ -321,11 +367,105 @@ public BatchLoaderScheduler getBatchLoaderScheduler() {
321367 * to some future time.
322368 *
323369 * @param batchLoaderScheduler the scheduler
324- *
325370 * @return the data loader options for fluent coding
326371 */
327372 public DataLoaderOptions setBatchLoaderScheduler (BatchLoaderScheduler batchLoaderScheduler ) {
328- this .batchLoaderScheduler = batchLoaderScheduler ;
329- return this ;
373+ return builder ().setBatchLoaderScheduler (batchLoaderScheduler ).build ();
374+ }
375+
376+ private Builder builder () {
377+ return new Builder (this );
378+ }
379+
380+ public static class Builder {
381+ private boolean batchingEnabled ;
382+ private boolean cachingEnabled ;
383+ private boolean cachingExceptionsEnabled ;
384+ private CacheKey <?> cacheKeyFunction ;
385+ private CacheMap <?, ?> cacheMap ;
386+ private ValueCache <?, ?> valueCache ;
387+ private int maxBatchSize ;
388+ private Supplier <StatisticsCollector > statisticsCollector ;
389+ private BatchLoaderContextProvider environmentProvider ;
390+ private ValueCacheOptions valueCacheOptions ;
391+ private BatchLoaderScheduler batchLoaderScheduler ;
392+
393+ public Builder () {
394+ this (new DataLoaderOptions ()); // use the defaults of the DataLoaderOptions for this builder
395+ }
396+
397+ Builder (DataLoaderOptions other ) {
398+ this .batchingEnabled = other .batchingEnabled ;
399+ this .cachingEnabled = other .cachingEnabled ;
400+ this .cachingExceptionsEnabled = other .cachingExceptionsEnabled ;
401+ this .cacheKeyFunction = other .cacheKeyFunction ;
402+ this .cacheMap = other .cacheMap ;
403+ this .valueCache = other .valueCache ;
404+ this .maxBatchSize = other .maxBatchSize ;
405+ this .statisticsCollector = other .statisticsCollector ;
406+ this .environmentProvider = other .environmentProvider ;
407+ this .valueCacheOptions = other .valueCacheOptions ;
408+ this .batchLoaderScheduler = other .batchLoaderScheduler ;
409+ }
410+
411+ public Builder setBatchingEnabled (boolean batchingEnabled ) {
412+ this .batchingEnabled = batchingEnabled ;
413+ return this ;
414+ }
415+
416+ public Builder setCachingEnabled (boolean cachingEnabled ) {
417+ this .cachingEnabled = cachingEnabled ;
418+ return this ;
419+ }
420+
421+ public Builder setCachingExceptionsEnabled (boolean cachingExceptionsEnabled ) {
422+ this .cachingExceptionsEnabled = cachingExceptionsEnabled ;
423+ return this ;
424+ }
425+
426+ public Builder setCacheKeyFunction (CacheKey <?> cacheKeyFunction ) {
427+ this .cacheKeyFunction = cacheKeyFunction ;
428+ return this ;
429+ }
430+
431+ public Builder setCacheMap (CacheMap <?, ?> cacheMap ) {
432+ this .cacheMap = cacheMap ;
433+ return this ;
434+ }
435+
436+ public Builder setValueCache (ValueCache <?, ?> valueCache ) {
437+ this .valueCache = valueCache ;
438+ return this ;
439+ }
440+
441+ public Builder setMaxBatchSize (int maxBatchSize ) {
442+ this .maxBatchSize = maxBatchSize ;
443+ return this ;
444+ }
445+
446+ public Builder setStatisticsCollector (Supplier <StatisticsCollector > statisticsCollector ) {
447+ this .statisticsCollector = statisticsCollector ;
448+ return this ;
449+ }
450+
451+ public Builder setBatchLoaderContextProvider (BatchLoaderContextProvider environmentProvider ) {
452+ this .environmentProvider = environmentProvider ;
453+ return this ;
454+ }
455+
456+ public Builder setValueCacheOptions (ValueCacheOptions valueCacheOptions ) {
457+ this .valueCacheOptions = valueCacheOptions ;
458+ return this ;
459+ }
460+
461+ public Builder setBatchLoaderScheduler (BatchLoaderScheduler batchLoaderScheduler ) {
462+ this .batchLoaderScheduler = batchLoaderScheduler ;
463+ return this ;
464+ }
465+
466+ public DataLoaderOptions build () {
467+ return new DataLoaderOptions (this );
468+ }
469+
330470 }
331471}
0 commit comments