package pt.ul.jarmus;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Phaser;
import java.util.logging.Logger;
import pt.ul.armus.Armus;
import pt.ul.armus.ArmusFactory;
import pt.ul.armus.conf.ConfigurationLoader;
import pt.ul.armus.conf.MainConfiguration;
import pt.ul.armus.conf.in.ParserException;
import pt.ul.jarmus.checkers.ResourceRegister;
import pt.ul.jarmus.checkers.CountDownLatchChecker;
import pt.ul.jarmus.checkers.CyclicBarrierChecker;
import pt.ul.jarmus.checkers.PhaserChecker;
/**
* Controls the internals of JArmus.
*
* @author Tiago Cogumbreiro
*
*/
public class JArmusSetup {
private static final Logger LOGGER = Logger.getLogger(JArmusSetup.class
.getName());
private volatile JArmusController defaultEntry;
private final ConcurrentMap<Class<?>, ResourceRegister<?>> registers = new ConcurrentHashMap<>();
{
registers.put(CyclicBarrier.class, CyclicBarrierChecker.DEFAULT);
registers.put(Phaser.class, PhaserChecker.DEFAULT);
registers.put(CountDownLatch.class, CountDownLatchChecker.DEFAULT);
}
/**
* The JArmusController provides the main facade for manipulating JArmus
* internals.
*
* @param controller
*/
public synchronized void setController(JArmusController controller) {
if (controller == null) {
throw new IllegalArgumentException("Handler cannot be null.");
}
if (defaultEntry != null) {
defaultEntry.stop();
}
defaultEntry = controller;
defaultEntry.start();
}
public synchronized JArmusController getController() {
if (defaultEntry == null) {
try {
// default controller
final MainConfiguration conf = ConfigurationLoader
.parseFromSystem();
final JArmusController ctl = createControllerFrom(conf);
setController(ctl);
} catch (ParserException e) {
LOGGER.severe("Could not initialize JArmus");
throw new RuntimeException(e); // Crash and burn
}
}
return defaultEntry;
}
public <T> void registerChecker(Class<T> cls, ResourceRegister<T> checker) {
if (checker == null) {
throw new IllegalArgumentException("checker != null");
}
registers.put(cls, checker);
}
public <T> void deregisterChecker(Class<T> cls) {
registers.remove(cls);
}
/**
* Registers a synchroniser with JArmus.
*
* @param synch
* @param cls
*/
public <T, S extends T> void registerSynchronizer(S synch, Class<T> cls) {
ResourceRegister<T> checker = getResourceRegisterFor(cls);
if (checker == null) {
throw new IllegalArgumentException("Unsupported: " + cls);
}
checker.register(synch);
}
/**
* Returns the associated resource register.
*
* @param cls
* @return
*/
@SuppressWarnings("unchecked")
public <T> ResourceRegister<T> getResourceRegisterFor(Class<T> cls) {
return (ResourceRegister<T>) registers.get(cls);
}
/**
* Utility method to create the default controller given a
* {@link MainConfiguration}.
*
* @param conf
* @return
* @throws InstantiationException
* @throws IllegalAccessException
*/
public static JArmusController createControllerFrom(MainConfiguration conf) {
final Armus ver = ArmusFactory.build(conf);
return new JArmusControllerImpl(ver);
}
}