View Javadoc

1   package com.atlassian.sal.core.executor;
2   
3   import com.atlassian.sal.api.executor.ThreadLocalContextManager;
4   
5   import java.util.concurrent.Callable;
6   
7   import static com.google.common.base.Preconditions.checkNotNull;
8   
9   /**
10   * A wrapping callable that copies the thread local state into the calling code
11   *
12   * @since 2.0
13   */
14  class ThreadLocalDelegateCallable<C, T> implements Callable<T>
15  {
16      private final Callable<T> delegate;
17      private final ThreadLocalContextManager<C> manager;
18      private final C context;
19      private final ClassLoader contextClassLoader;
20  
21      /**
22       * Create a new callable
23       *
24       * @param manager The context manager to get the context from
25       * @param delegate The callable to delegate to
26       */
27      ThreadLocalDelegateCallable(ThreadLocalContextManager<C> manager, Callable<T> delegate)
28      {
29          this.delegate = checkNotNull(delegate);
30          this.manager = checkNotNull(manager);
31          this.context = manager.getThreadLocalContext();
32          this.contextClassLoader = Thread.currentThread().getContextClassLoader();
33      }
34  
35      public T call() throws Exception
36      {
37          ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
38          try
39          {
40              Thread.currentThread().setContextClassLoader(contextClassLoader);
41              manager.setThreadLocalContext(context);
42              return delegate.call();
43          }
44          finally
45          {
46              Thread.currentThread().setContextClassLoader(oldContextClassLoader);
47              manager.clearThreadLocalContext();
48          }
49      }
50  }