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);
}
}