blob: 7196af5c4ee25daafce044ec8981693c2b4b65a6 [file] [log] [blame]
/*******************************************************************************
* Copyright 2014 Trevor Robinson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.scurrilous.circe;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ServiceLoader;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Static utility methods for discovering {@link HashProvider} instances.
*/
public final class HashProviders {
static final Collection<HashProvider> ALL_PROVIDERS = getAllProviders();
private static Collection<HashProvider> getAllProviders() {
final ServiceLoader<HashProvider> loader = ServiceLoader.load(HashProvider.class);
final LinkedList<HashProvider> providers = new LinkedList<>();
for (final HashProvider provider : loader)
providers.add(provider);
return Collections.unmodifiableList(new ArrayList<>(providers));
}
private HashProviders() {
}
/**
* Returns an iterator over all known {@link HashProvider} instances.
*
* @return an iterator over all HashProviders
*/
public static Iterator<HashProvider> iterator() {
return ALL_PROVIDERS.iterator();
}
/**
* Returns the best hash provider supporting at least a stateful
* implementation of a hash function with the given parameters.
*
* @param params the parameters defining the hash function
* @return the best hash provider for the given parameters
* @throws UnsupportedOperationException if no provider supports the
* parameters
*/
public static HashProvider best(HashParameters params) {
return best(params, EnumSet.of(HashSupport.STATEFUL));
}
/**
* Returns the best hash provider supporting at least the given flags for a
* hash function with the given parameters.
*
* @param params the parameters defining the hash function
* @param required the required support flags for a provider to be
* considered
* @return the best hash provider for the given parameters
* @throws UnsupportedOperationException if no provider supports the
* parameters
*/
public static HashProvider best(HashParameters params, EnumSet<HashSupport> required) {
HashProvider result = null;
EnumSet<HashSupport> resultSupport = null;
for (final HashProvider provider : ALL_PROVIDERS) {
final EnumSet<HashSupport> support = provider.querySupport(params);
if (support.containsAll(required) &&
(result == null || HashSupport.compare(support, resultSupport) < 0)) {
result = provider;
resultSupport = support;
}
}
if (result == null)
throw new UnsupportedOperationException();
return result;
}
/**
* Returns a map of hash providers supporting at least a stateful
* implementation of a hash function with the given parameters.
*
* @param params the parameters defining the hash function
* @return a sorted map of hash support flags to hash providers
*/
public static SortedMap<EnumSet<HashSupport>, HashProvider> search(HashParameters params) {
return search(params, EnumSet.of(HashSupport.STATEFUL));
}
/**
* Returns a map of hash providers supporting at least the given flags for a
* hash function with the given parameters.
*
* @param params the parameters defining the hash function
* @param required the required support flags for a provider to be included
* @return a sorted map of hash support flags to hash providers
*/
public static SortedMap<EnumSet<HashSupport>, HashProvider> search(HashParameters params,
EnumSet<HashSupport> required) {
final SortedMap<EnumSet<HashSupport>, HashProvider> result = new TreeMap<>(
new HashSupport.SetComparator());
for (final HashProvider provider : ALL_PROVIDERS) {
final EnumSet<HashSupport> support = provider.querySupport(params);
if (support.containsAll(required))
result.put(support, provider);
}
return result;
}
}