package dbfit.api; import dbfit.annotations.DatabaseEnvironment; import org.reflections.Reflections; import java.lang.reflect.Constructor; import java.util.HashMap; import java.util.Map; public class DbEnvironmentFactory { private void initDefaultEnvironments() { Reflections reflections = new Reflections("dbfit"); for (Class<?> c: reflections.getTypesAnnotatedWith(DatabaseEnvironment.class)) { DatabaseEnvironment envAnnotation = c.getAnnotation(DatabaseEnvironment.class); registerEnv(envAnnotation.name(), envAnnotation.driver()); } } private static DBEnvironment environment; public static DBEnvironment getDefaultEnvironment(){ return environment; } public static void setDefaultEnvironment(DBEnvironment newDefaultEnvironment){ environment=newDefaultEnvironment; } public static DbEnvironmentFactory newFactoryInstance() { DbEnvironmentFactory factory = new DbEnvironmentFactory(); factory.initDefaultEnvironments(); return factory; } public static class EnvironmentDescriptor { public String environmentName; public String driverClassName; private void checkDriver() { try { Class.forName(driverClassName); } catch (Exception e) { throw new Error("Cannot load " + environmentName + " database driver " + driverClassName + ". Is the JDBC driver on the classpath?", e); } } public String getEnvironmentClassName() { return "dbfit.environment." + environmentName + "Environment"; } public EnvironmentDescriptor(String environmentName, String driverClassName) { this.environmentName = environmentName; this.driverClassName = driverClassName; } public DBEnvironment createEnvironmentInstance() { checkDriver(); try { Class<?> envClass = Class.forName(getEnvironmentClassName()); Constructor ctor = envClass.getConstructor(String.class); DBEnvironment oe = (DBEnvironment) ctor.newInstance(driverClassName); return oe; } catch (Exception e) { throw new Error(e); } } } private Map<String, EnvironmentDescriptor> environments = new HashMap<String, EnvironmentDescriptor>(); private DbEnvironmentFactory() { } private static String normalise(String environmentName) { return environmentName.trim().toUpperCase(); } public void registerEnv(String environmentName, String driverClassName) { environments.put(normalise(environmentName), new EnvironmentDescriptor(environmentName, driverClassName)); } public EnvironmentDescriptor unregisterEnv(String environmentName) { return environments.remove(normalise(environmentName)); } private EnvironmentDescriptor getEnvironmentDescriptor(String requestedEnv) { return environments.get(normalise(requestedEnv)); } public DBEnvironment createEnvironmentInstance(String requestedEnv) { EnvironmentDescriptor descriptor = getEnvironmentDescriptor(requestedEnv); if (null == descriptor) { throw new IllegalArgumentException("DB Environment not supported:" + requestedEnv); } return descriptor.createEnvironmentInstance(); } public static DBEnvironment newEnvironmentInstance(String requestedEnv) { return newFactoryInstance().createEnvironmentInstance(requestedEnv); } }