org.wildfly.security.provider.util.ProviderUtil Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2015 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* 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 org.wildfly.security.provider.util;
import org.wildfly.common.Assert;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Utilities for dealing with security providers.
*
* @author David M. Lloyd
*/
public final class ProviderUtil {
/**
* A {@link Supplier} to obtain the {@link Provider} array of providers available from {@link Security#getProviders()}.
*/
public static final Supplier INSTALLED_PROVIDERS = Security::getProviders;
/**
* Find the first provider from the supplier which provides the given service type and algorithm name. The simple
* name of the service type class is used to identify the service.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providerSupplier the provider supplier (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type as a class name (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider, or {@code null} if none is found
*/
public static Provider findProvider(Supplier providerSupplier, String providerName, Class> serviceType, String algorithm) {
Assert.checkNotNullParam("providerSupplier", providerSupplier);
return findProvider(providerSupplier.get(), providerName, serviceType, algorithm);
}
/**
* Find the first provider from the supplier which provides the given service type and algorithm name. The simple
* name of the service type class is used to identify the service.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providers the providers to searchr (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type as a class name (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider, or {@code null} if none is found
*/
public static Provider findProvider(Provider[] providers, String providerName, Class> serviceType, String algorithm) {
Assert.checkNotNullParam("serviceType", serviceType);
return findProvider(providers, providerName, serviceType.getSimpleName(), algorithm);
}
/**
* Find the first provider from the supplier which provides the given service type and algorithm name.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providerSupplier the provider supplier (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider, or {@code null} if none is found
*/
public static Provider findProvider(Supplier providerSupplier, String providerName, String serviceType, String algorithm) {
Assert.checkNotNullParam("providerSupplier", providerSupplier);
return findProvider(providerSupplier.get(), providerName, serviceType, algorithm);
}
/**
* Find the first provider from the supplier which provides the given service type and algorithm name.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providers the providers to search (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider, or {@code null} if none is found
*/
public static Provider findProvider(Provider[] providers, String providerName, String serviceType, String algorithm) {
final Provider.Service service = findProviderService(providers, providerName, serviceType, algorithm);
return service == null ? null : service.getProvider();
}
/**
* Find a provider service which provides the given service type and algorithm name.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providerSupplier the provider supplier (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider service, or {@code null} if none is found
*/
public static Provider.Service findProviderService(Supplier providerSupplier, String providerName, Class> serviceType, String algorithm) {
Assert.checkNotNullParam("providerSupplier", providerSupplier);
return findProviderService(providerSupplier.get(), providerName, serviceType, algorithm);
}
/**
* Find a provider service which provides the given service type and algorithm name.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providers the providers to search (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider service, or {@code null} if none is found
*/
public static Provider.Service findProviderService(Provider[] providers, String providerName, Class> serviceType, String algorithm) {
Assert.checkNotNullParam("serviceType", serviceType);
return findProviderService(providers, providerName, serviceType.getSimpleName(), algorithm);
}
/**
* Find a provider service which provides the given service type and algorithm name.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providerSupplier the provider supplier (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider service, or {@code null} if none is found
*/
public static Provider.Service findProviderService(Supplier providerSupplier, String providerName, String serviceType, String algorithm) {
Assert.checkNotNullParam("providerSupplier", providerSupplier);
return findProviderService(providerSupplier.get(), providerName, serviceType, algorithm);
}
/**
* Find a provider service which provides the given service type and algorithm name.
*
* If a providerName is specified the match will only be tested against providers with the name specified.
*
* @param providers the providers to search (must not be {@code null})
* @param providerName the name of the provider, can be {@code null}
* @param serviceType the service type (must not be {@code null})
* @param algorithm the algorithm name (must not be {@code null})
* @return the provider service, or {@code null} if none is found
*/
public static Provider.Service findProviderService(Provider[] providers, String providerName, String serviceType, String algorithm) {
Assert.checkNotNullParam("providers", providers);
Assert.checkNotNullParam("serviceType", serviceType);
Assert.checkNotNullParam("algorithm", algorithm);
for (int i = 0; i < providers.length; i++) {
Provider provider = Assert.checkNotNullArrayParam("providers", i, providers[i]);
if (providerName == null || providerName.equals(provider.getName())) {
Provider.Service providerService = provider.getService(serviceType, algorithm);
if (providerService != null) {
return providerService;
}
}
}
return null;
}
/**
* Find a provider service which matches the given predicate.
*
* @param providerSupplier the provider supplier
* @param matchPredicate the predicate to test
* @return the provider service, or {@code null} if none is found
*/
public static Provider.Service findProviderService(Supplier providerSupplier, Predicate matchPredicate) {
Assert.checkNotNullParam("providerSupplier", providerSupplier);
return findProviderService(providerSupplier.get(), matchPredicate);
}
/**
* Find a provider service which matches the given predicate.
*
* @param providers the providers to search
* @param matchPredicate the predicate to test
* @return the provider service, or {@code null} if none is found
*/
public static Provider.Service findProviderService(Provider[] providers, Predicate matchPredicate) {
Assert.checkNotNullParam("providers", providers);
Assert.checkNotNullParam("matchPredicate", matchPredicate);
for (int i = 0; i < providers.length; i++) {
for (Provider.Service service : Assert.checkNotNullArrayParam("providers", i, providers[i]).getServices()) {
if (matchPredicate.test(service)) {
return service;
}
}
}
return null;
}
/**
* Create a {@link Supplier} of providers that is an aggregation of the result of multiple suppliers.
*
* The aggregation will be performed the first time the supplier is called and the results cached.
*
* @param suppliers the suppliers to aggregate.
* @return A supplier which will return an aggregation of all of the suppliers.
*/
public static Supplier aggregate(final Supplier... suppliers) {
Assert.checkNotNullParam("suppliers", suppliers);
return new Supplier() {
private volatile Provider[] result = null;
@Override
public Provider[] get() {
if (result == null) {
synchronized (suppliers) {
if (result == null) {
ArrayList resolvedProviders = new ArrayList<>(suppliers.length);
int count = 0;
for (Supplier current : suppliers) {
Provider[] resolved = current.get();
count += resolved.length;
resolvedProviders.add(resolved);
}
Provider[] tempResult = new Provider[count];
count = 0;
for (Provider[] p : resolvedProviders) {
System.arraycopy(p, 0, tempResult, (count += p.length) - p.length, p.length);
}
result = tempResult;
}
}
}
return result.clone();
}
};
}
}