com.google.inject.internal.FailableCache Maven / Gradle / Ivy
package com.google.inject.internal;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import java.util.Map;
/**
* Lazily creates (and caches) values for keys. If creating the value fails (with errors), an
* exception is thrown on retrieval.
*/
public abstract class FailableCache {
private final LoadingCache delegate = CacheBuilder.newBuilder()
.build(new CacheLoader<>() {
public Object load(K key) {
Errors errors = new Errors();
V result = null;
try {
result = FailableCache.this.create(key, errors);
} catch (ErrorsException e) {
errors.merge(e.getErrors());
}
return errors.hasErrors() ? errors : result;
}
});
protected abstract V create(K key, Errors errors) throws ErrorsException;
public V get(K key, Errors errors) throws ErrorsException {
Object resultOrError = delegate.getUnchecked(key);
if (resultOrError instanceof Errors) {
errors.merge((Errors) resultOrError);
throw errors.toException();
} else {
@SuppressWarnings("unchecked") // create returned a non-error result, so this is safe
V result = (V) resultOrError;
return result;
}
}
boolean remove(K key) {
return delegate.asMap().remove(key) != null;
}
Map asMap() {
return Maps.transformValues(Maps.filterValues(ImmutableMap.copyOf(delegate.asMap()),
resultOrError -> !(resultOrError instanceof Errors)),
resultOrError -> {
@SuppressWarnings("unchecked") // create returned a non-error result, so this is safe
V result = (V) resultOrError;
return result;
});
}
}