package fr.openwide.core.commons.util.context; import java.util.concurrent.Callable; import javax.annotation.concurrent.NotThreadSafe; /** * Encapsulates the concept of setting up and tearing down an implementation-defined context. * * <p>Setting up a context typically involves altering a state, and tearing it down typically means restoring the * previous state (or any clean state, depending on the implementor's constraints)). * <p>The state may for example be stored in a {@link ThreadLocal}, or in the object that created this * {@link IExecutionContext}. * * <p>Implementations are not required to be thread-safe. */ @NotThreadSafe public interface IExecutionContext { /** * Set up the context for execution and return an {@link ITearDownHandle} that will tear down the context upon * {@link ITearDownHandle#close()}. * * <p>This is generally used this way: * <code><pre> * IExecutionContext context = ... ; * try (AutoCloseable openContext = context.open()) { * // Do stuff that requires the context * } * // Here the context has been automatically closed * </pre></code> */ ITearDownHandle open(); /** * An {@link AutoCloseable} that may not throw checked exceptions. */ public interface ITearDownHandle extends AutoCloseable { @Override public void close(); } /** * Set up the context, run the given {@link Runnable}, then tear down the context. * <p>The implementation must tear down the context even if the runnable throws an exception. */ void run(Runnable runnable); /** * Set up the context, run the given {@link callable}, tear down the context, and return the callable's result * (if any, i.e. if it didn't throw an exception). * <p>The implementation must tear down the context even if the runnable throws an exception. */ <T> T run(Callable<T> callable) throws Exception; /** * Test if the context is ready to be opened */ boolean isReady(); }