package pt.ist.fenixframework.atomic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import pt.ist.fenixframework.Atomic;
import pt.ist.fenixframework.dml.CodeGenerator;
/**
* This DefaultContextFactoryViaReflection tries to find, via reflection, the {@link
* pt.ist.fenixframework.atomic.ContextFactory} class of the backend in use. It does so, first by
* getting the current <code>BackEndId</code> (by reflection) and then by getting the factory class
* (through <code>getAtomicContextFactoryClass()</code> --- again by reflection). It delegates to
* that factory the creation of the appropriate {@link AtomicContext}. If it fails, it throws an
* Error, indicating such condition.
*/
public final class DefaultContextFactoryViaReflection extends ContextFactory {
private static final Logger logger = LoggerFactory.getLogger(DefaultContextFactoryViaReflection.class);
private static final String BACKEND_ID_FULL_CLASS_NAME = CodeGenerator.BACKEND_PACKAGE + "." +
CodeGenerator.ABSTRACT_BACKEND_ID_CLASS;
// This code uses reflection, but it only runs once per occurrence of the @Atomic annotation in
// the code, regardless of the number of times that such method runs.
public static AtomicContext newContext(Atomic atomic) {
logger.trace("Creating a new AtomicContext via reflection");
try {
// GOAL: currentBackendId = BackEndId.getInstance();
Class backendIdClass = Class.forName(BACKEND_ID_FULL_CLASS_NAME);
Method getInstance = backendIdClass.getMethod("getBackEndId");
Object currentBackendId = getInstance.invoke(null);
// GOAL: Class<? extends ContextFactory> factoryClass = BackEndId.getAtomicContextFactoryClass()
Method getAtomicContextFactoryClass = currentBackendId.getClass().getMethod("getAtomicContextFactoryClass");
Class<? extends ContextFactory> factoryClass = (Class<? extends ContextFactory>)getAtomicContextFactoryClass.invoke(currentBackendId);
// GOAL: return (AtomicContext)contextFactory.newContext(atomic);
Method newContext = factoryClass.getMethod("newContext", new Class[]{Atomic.class});
return (AtomicContext)newContext.invoke(null, new Object[]{atomic});
} catch (Exception e) {
throw new Error("Could not obtain an AtomicContext via the ContextFactory", e);
}
}
}