cucumber.runtime.Reflections Maven / Gradle / Ivy
package cucumber.runtime;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
public class Reflections {
private final ClassFinder classFinder;
public Reflections(ClassFinder classFinder) {
this.classFinder = classFinder;
}
public T instantiateExactlyOneSubclass(Class parentType, String packageName, Class[] constructorParams, Object[] constructorArgs) {
Collection extends T> instances = instantiateSubclasses(parentType, packageName, constructorParams, constructorArgs);
if (instances.size() == 1) {
return instances.iterator().next();
} else if (instances.size() == 0) {
throw new NoInstancesException(parentType);
} else {
throw new TooManyInstancesException(instances);
}
}
public Collection extends T> instantiateSubclasses(Class parentType, String packageName, Class[] constructorParams, Object[] constructorArgs) {
Collection result = new HashSet();
for (Class extends T> clazz : classFinder.getDescendants(parentType, packageName)) {
if (Utils.isInstantiable(clazz) && hasConstructor(clazz, constructorParams)) {
result.add(newInstance(constructorParams, constructorArgs, clazz));
}
}
return result;
}
public T newInstance(Class[] constructorParams, Object[] constructorArgs, Class extends T> clazz) {
Constructor extends T> constructor = null;
try {
constructor = clazz.getConstructor(constructorParams);
try {
return constructor.newInstance(constructorArgs);
} catch (Exception e) {
String message = String.format("Failed to instantiate %s with %s", constructor.toGenericString(), Arrays.asList(constructorArgs));
throw new CucumberException(message, e);
}
} catch (NoSuchMethodException e) {
throw new CucumberException(e);
}
}
private boolean hasConstructor(Class> clazz, Class[] paramTypes) {
try {
clazz.getConstructor(paramTypes);
return true;
} catch (NoSuchMethodException e) {
return false;
}
}
}