package tc.oc.pgm.match; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import javax.annotation.Nullable; import tc.oc.commons.core.reflect.Methods; import tc.oc.pgm.module.ModuleLoadException; /** * Creates a {@link MatchModule} unconditionally for every match. The module * must have a public constructor that accepts one {@link Match} parameter. */ public class FixtureMatchModuleFactory<T extends MatchModule> implements MatchModuleFactory<T> { private final Constructor<T> constructor; public FixtureMatchModuleFactory(Class<T> matchModuleClass) { if(Modifier.isAbstract(matchModuleClass.getModifiers())) { throw new IllegalArgumentException(matchModuleClass.getName() + " is abstract"); } try { this.constructor = matchModuleClass.getConstructor(Match.class); } catch(NoSuchMethodException e) { throw new IllegalArgumentException("Missing constructor " + matchModuleClass.getSimpleName() + "(Match) in class " + matchModuleClass.getName()); } Methods.assertPublicThrows(constructor, ModuleLoadException.class); } @Override public @Nullable T createMatchModule(Match match) throws ModuleLoadException { try { return constructor.newInstance(match); } catch(InvocationTargetException e) { if(e.getCause() instanceof ModuleLoadException) { throw (ModuleLoadException) e.getCause(); } else { // Already verified that it cannot throw any other checked exceptions throw (RuntimeException) e.getCause(); } } catch(InstantiationException | IllegalAccessException e) { // This should be pretty much impossible due to the checks in the constructor throw new IllegalStateException(e); } } }