package org.magenta.core.injection; import java.util.concurrent.Callable; import org.magenta.DataSpecification; import org.magenta.Fixture; public class ThreadLocalDataDomainSupplier<S extends DataSpecification> implements FixtureContext<S> { private ThreadLocal<Fixture> current = new ThreadLocal<Fixture>(); protected void setContext(Fixture<? extends S> domain) { current.set(domain); } protected void removeContext() { current.set(null); } @Override public Fixture<S> get() { return current.get(); } @Override public <D> D execute(Callable<D> callable, Fixture<? extends S> fixture) { if (get() != null && !fixture.equals(get())) { throw new IllegalStateException("Illegal attemp to set a new context when one is already active"); } boolean responsible = false; try { if (get() == null) { responsible = true; setContext(fixture); } D data = uncheckedCall(callable); return data; } finally { if (responsible) { removeContext(); } } } private <D> D uncheckedCall(Callable<D> callable) { try { return callable.call(); } catch (RuntimeException re) { throw re; } catch (Exception e) { throw new RuntimeException(e); } } @Override public void post(Object event) { get().getEventBus().post(event); } }