2022-07-20 13:18:57 +02:00
|
|
|
package fr.pandacube.lib.util;
|
2021-08-08 12:56:36 +02:00
|
|
|
|
2023-08-27 13:37:17 +02:00
|
|
|
import fr.pandacube.lib.util.function.SupplierException;
|
|
|
|
|
2021-08-08 12:56:36 +02:00
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
/**
|
2023-08-27 13:37:17 +02:00
|
|
|
* A Supplier that cache the value the first time it is called.
|
2021-08-08 12:56:36 +02:00
|
|
|
*
|
2023-08-27 13:37:17 +02:00
|
|
|
* @param <T> the type of the supplied value.
|
|
|
|
* @param <E> the exception type that may be thrown by the source supplier.
|
2021-08-08 12:56:36 +02:00
|
|
|
*/
|
2023-08-27 13:37:17 +02:00
|
|
|
public class CachedSupplierException<T, E extends Exception> implements SupplierException<T, E> {
|
2021-08-08 12:56:36 +02:00
|
|
|
|
|
|
|
private T cachedValue;
|
2023-08-27 13:37:17 +02:00
|
|
|
private final SupplierException<T, E> source;
|
2021-08-08 12:56:36 +02:00
|
|
|
private boolean cached = false;
|
2022-07-28 01:13:35 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a lazy value loader that will call the provided supplier to get the value.
|
|
|
|
* @param s the supplier from which the value is fetched.
|
|
|
|
*/
|
2023-08-27 13:37:17 +02:00
|
|
|
public CachedSupplierException(SupplierException<T, E> s) {
|
|
|
|
source = Objects.requireNonNull(s);
|
2021-08-08 12:56:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-08-27 13:37:17 +02:00
|
|
|
* Get the value, from cache or from the provider if it's not yet cached.
|
|
|
|
* <p>
|
2022-07-28 01:13:35 +02:00
|
|
|
* If the provider throws an exception, it will be redirected to the caller as is, and no value will be cached
|
|
|
|
* (the next call to this method will execute the supplier again).
|
2021-08-08 12:56:36 +02:00
|
|
|
*/
|
|
|
|
@Override
|
2023-08-27 13:37:17 +02:00
|
|
|
public synchronized T get() throws E {
|
2022-07-28 01:13:35 +02:00
|
|
|
if (!cached)
|
2023-08-27 13:37:17 +02:00
|
|
|
set(source.get());
|
2021-08-08 12:56:36 +02:00
|
|
|
return cachedValue;
|
|
|
|
}
|
2022-07-28 01:13:35 +02:00
|
|
|
|
|
|
|
/**
|
2023-08-27 13:37:17 +02:00
|
|
|
* Reset the cached value. The next call to {@link #get()} will get the value from the source.
|
2022-07-28 01:13:35 +02:00
|
|
|
*/
|
2021-08-08 12:56:36 +02:00
|
|
|
public synchronized void reset() {
|
|
|
|
cached = false;
|
|
|
|
cachedValue = null;
|
|
|
|
}
|
2022-07-28 01:13:35 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Manually set the value to the provided one.
|
|
|
|
* @param value the value to put in the cache.
|
|
|
|
*/
|
2021-08-08 12:56:36 +02:00
|
|
|
public synchronized void set(T value) {
|
|
|
|
cachedValue = value;
|
|
|
|
cached = true;
|
|
|
|
}
|
|
|
|
|
2023-08-27 01:48:09 +02:00
|
|
|
/**
|
|
|
|
* Tells if the value is currently set or not.
|
|
|
|
* @return true if the value has been set by calling the method {@link #get()} or {@link #set(Object)} but not yet
|
|
|
|
* reset by {@link #reset()}, or false otherwise.
|
|
|
|
*/
|
|
|
|
public synchronized boolean isSet() {
|
|
|
|
return cached;
|
|
|
|
}
|
|
|
|
|
2021-08-08 12:56:36 +02:00
|
|
|
}
|