ContractsFactoryFinder.java
package io.github.jonloucks.contracts.api;
import java.lang.reflect.Constructor;
import java.util.Optional;
import java.util.ServiceLoader;
import static io.github.jonloucks.contracts.api.Checks.configCheck;
import static io.github.jonloucks.contracts.api.Checks.nullCheck;
final class ContractsFactoryFinder {
private final Contracts.Config config;
ContractsFactoryFinder(Contracts.Config config) {
this.config = configCheck(config);
}
ContractsFactory find() {
return createByReflection()
.or(this::createByServiceLoader)
.orElseThrow(this::newNotFoundException);
}
private Optional<? extends ContractsFactory> createByServiceLoader() {
if (config.useServiceLoader()) {
try {
return ServiceLoader.load(getServiceFactoryClass()).findFirst();
} catch (Throwable ignored) {
return Optional.empty();
}
}
return Optional.empty();
}
private Class<? extends ContractsFactory> getServiceFactoryClass() {
return nullCheck(config.serviceLoaderClass(), "Contracts Service Loader class must be present.");
}
private Optional<ContractsFactory> createByReflection() {
if (config.useReflection()) {
final String className = getClassName();
if (className.isEmpty()) {
return Optional.empty();
}
try {
return Optional.of((ContractsFactory) getConstructor(className).newInstance());
} catch (Throwable ignored) {
return Optional.empty();
}
}
return Optional.empty();
}
private String getClassName() {
return nullCheck(config.reflectionClassName(), "Reflection reflection class name must be present.");
}
private Constructor<?> getConstructor(String className) throws Throwable {
return Class.forName(className).getConstructor();
}
private ContractException newNotFoundException() {
return new ContractException("Unable to find Contracts factory.");
}
}