package org.ehcache.core.store;
import org.ehcache.config.ResourceType;
import org.ehcache.core.spi.ServiceLocator;
import org.ehcache.core.spi.store.Store;
import org.ehcache.core.spi.store.WrapperStore;
import org.ehcache.spi.service.ServiceProvider;
import org.ehcache.spi.service.Service;
import org.ehcache.spi.service.ServiceConfiguration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public final class StoreSupport {
private StoreSupport() {
}
public static Store.Provider selectWrapperStoreProvider(ServiceProvider<Service> serviceProvider, Collection<ServiceConfiguration<?>> serviceConfigs) {
Collection<WrapperStore.Provider> storeProviders = serviceProvider.getServicesOfType(WrapperStore.Provider.class);
Optional<Tuple<Integer, WrapperStore.Provider>> wrapperProvider = storeProviders.stream()
.map(provider -> new Tuple<>(provider.wrapperStoreRank(serviceConfigs), provider))
.filter(providerTuple -> providerTuple.x != 0)
.max(Comparator.comparingInt(value -> value.x));
return wrapperProvider.map(providerTuple -> providerTuple.y).orElse(null);
}
private static class Tuple<X, Y> {
final X x;
final Y y;
Tuple(X x, Y y) {
this.x = x;
this.y = y;
}
}
public static Store.Provider selectStoreProvider(
ServiceProvider<Service> serviceProvider, Set<ResourceType<?>> resourceTypes, Collection<ServiceConfiguration<?>> serviceConfigs) {
Collection<Store.Provider> storeProviders = serviceProvider.getServicesOfType(Store.Provider.class);
List<Store.Provider> filteredStoreProviders = storeProviders.stream().filter(provider -> !(provider instanceof WrapperStore.Provider)).collect(Collectors.toList());
int highRank = 0;
List<Store.Provider> rankingProviders = new ArrayList<>();
for (Store.Provider provider : filteredStoreProviders) {
int rank = provider.rank(resourceTypes, serviceConfigs);
if (rank > highRank) {
highRank = rank;
rankingProviders.clear();
rankingProviders.add(provider);
} else if (rank != 0 && rank == highRank) {
rankingProviders.add(provider);
}
}
if (rankingProviders.isEmpty()) {
StringBuilder sb = new StringBuilder("No Store.Provider found to handle configured resource types ");
sb.append(resourceTypes);
sb.append(" from ");
formatStoreProviders(filteredStoreProviders, sb);
throw new IllegalStateException(sb.toString());
} else if (rankingProviders.size() > 1) {
StringBuilder sb = new StringBuilder("Multiple Store.Providers found to handle configured resource types ");
sb.append(resourceTypes);
sb.append(": ");
formatStoreProviders(rankingProviders, sb);
throw new IllegalStateException(sb.toString());
}
return rankingProviders.get(0);
}
private static void formatStoreProviders(final Collection<Store.Provider> storeProviders, final StringBuilder sb) {
sb.append('{');
boolean prependSeparator = false;
for (final Store.Provider provider : storeProviders) {
if (prependSeparator) {
sb.append(", ");
} else {
prependSeparator = true;
}
sb.append(provider.getClass().getName());
}
sb.append('}');
}
}