@Test public void testCallable() throws Exception { assertEquals(5, this.context.callWithContext(new Callable<Integer>() { @Override public Integer call() throws Exception { return 5; } }).intValue()); }
@Override public <T> T callWithContext(final Callable<T> callable) throws Exception { final Object owner = new Object(); final Stack<ListenerInvocation> invocations = new Stack<>(); final boolean reentry = !ManagedContextUtils.setAndCheckOwner(owner); RuntimeException firstError = null; try { for (final ManagedContextListener<?> listener : listeners) { Object data = null; try { data = listener.onEnterContext(reentry); } catch (final RuntimeException e) { if (firstError == null) { firstError = e; } log.error("Failed onEnterContext for listener [{}]", listener, e); } invocations.push(new ListenerInvocation((ManagedContextListener<Object>) listener, data)); } try { if (firstError == null) { return callable.call(); } else { throwException(firstError); return null; } } finally { Throwable lastError = null; while (!invocations.isEmpty()) { final ListenerInvocation invocation = invocations.pop(); try { invocation.listener.onLeaveContext(invocation.data, reentry); } catch (final RuntimeException e) { lastError = e; log.error("Failed onLeaveContext for listener [{}]", invocation.listener, e); } } if (firstError == null && lastError != null) { throwException(lastError); } } } finally { if (ManagedContextUtils.clearOwner(owner)) { ManagedThreadLocal.reset(); } } }
DefaultManagedContext implements ManagedContext { @Override public <T> T callWithContext(final Callable<T> callable) throws Exception { final Object owner = new Object(); final Stack<ListenerInvocation> invocations = new Stack<>(); final boolean reentry = !ManagedContextUtils.setAndCheckOwner(owner); RuntimeException firstError = null; try { for (final ManagedContextListener<?> listener : listeners) { Object data = null; try { data = listener.onEnterContext(reentry); } catch (final RuntimeException e) { if (firstError == null) { firstError = e; } log.error("Failed onEnterContext for listener [{}]", listener, e); } invocations.push(new ListenerInvocation((ManagedContextListener<Object>) listener, data)); } try { if (firstError == null) { return callable.call(); } else { throwException(firstError); return null; } } finally { Throwable lastError = null; while (!invocations.isEmpty()) { final ListenerInvocation invocation = invocations.pop(); try { invocation.listener.onLeaveContext(invocation.data, reentry); } catch (final RuntimeException e) { lastError = e; log.error("Failed onLeaveContext for listener [{}]", invocation.listener, e); } } if (firstError == null && lastError != null) { throwException(lastError); } } } finally { if (ManagedContextUtils.clearOwner(owner)) { ManagedThreadLocal.reset(); } } } }
DefaultManagedContext implements ManagedContext { @Override public <T> T callWithContext(final Callable<T> callable) throws Exception { final Object owner = new Object(); final Stack<ListenerInvocation> invocations = new Stack<>(); final boolean reentry = !ManagedContextUtils.setAndCheckOwner(owner); RuntimeException firstError = null; try { for (final ManagedContextListener<?> listener : listeners) { Object data = null; try { data = listener.onEnterContext(reentry); } catch (final RuntimeException e) { if (firstError == null) { firstError = e; } log.error("Failed onEnterContext for listener [{}]", listener, e); } invocations.push(new ListenerInvocation((ManagedContextListener<Object>) listener, data)); } try { if (firstError == null) { return callable.call(); } else { throwException(firstError); return null; } } finally { Throwable lastError = null; while (!invocations.isEmpty()) { final ListenerInvocation invocation = invocations.pop(); try { invocation.listener.onLeaveContext(invocation.data, reentry); } catch (final RuntimeException e) { lastError = e; log.error("Failed onLeaveContext for listener [{}]", invocation.listener, e); } } if (firstError == null && lastError != null) { throwException(lastError); } } } finally { if (ManagedContextUtils.clearOwner(owner)) { ManagedThreadLocal.reset(); } } }  }
DefaultManagedContext implements ManagedContext { @Override public <T> T callWithContext(final Callable<T> callable) throws Exception { final Object owner = new Object(); final Stack<ListenerInvocation> invocations = new Stack<>(); final boolean reentry = !ManagedContextUtils.setAndCheckOwner(owner); RuntimeException firstError = null; try { for (final ManagedContextListener<?> listener : listeners) { Object data = null; try { data = listener.onEnterContext(reentry); } catch (final RuntimeException e) { if (firstError == null) { firstError = e; } log.error("Failed onEnterContext for listener [{}]", listener, e); } invocations.push(new ListenerInvocation((ManagedContextListener<Object>) listener, data)); } try { if (firstError == null) { return callable.call(); } else { throwException(firstError); return null; } } finally { Throwable lastError = null; while (!invocations.isEmpty()) { final ListenerInvocation invocation = invocations.pop(); try { invocation.listener.onLeaveContext(invocation.data, reentry); } catch (final RuntimeException e) { lastError = e; log.error("Failed onLeaveContext for listener [{}]", invocation.listener, e); } } if (firstError == null && lastError != null) { throwException(lastError); } } } finally { if (ManagedContextUtils.clearOwner(owner)) { ManagedThreadLocal.reset(); } } }  @Override void registerListener(final ManagedContextListener<?> listener); @Override void unregisterListener(final ManagedContextListener<?> listener); @Override void runWithContext(final Runnable run); @Override T callWithContext(final Callable<T> callable); List<ManagedContextListener<?>> getListeners(); void setListeners(final List<ManagedContextListener<?>> listeners); }
DefaultManagedContext implements ManagedContext { @Override public <T> T callWithContext(final Callable<T> callable) throws Exception { final Object owner = new Object(); final Stack<ListenerInvocation> invocations = new Stack<>(); final boolean reentry = !ManagedContextUtils.setAndCheckOwner(owner); RuntimeException firstError = null; try { for (final ManagedContextListener<?> listener : listeners) { Object data = null; try { data = listener.onEnterContext(reentry); } catch (final RuntimeException e) { if (firstError == null) { firstError = e; } log.error("Failed onEnterContext for listener [{}]", listener, e); } invocations.push(new ListenerInvocation((ManagedContextListener<Object>) listener, data)); } try { if (firstError == null) { return callable.call(); } else { throwException(firstError); return null; } } finally { Throwable lastError = null; while (!invocations.isEmpty()) { final ListenerInvocation invocation = invocations.pop(); try { invocation.listener.onLeaveContext(invocation.data, reentry); } catch (final RuntimeException e) { lastError = e; log.error("Failed onLeaveContext for listener [{}]", invocation.listener, e); } } if (firstError == null && lastError != null) { throwException(lastError); } } } finally { if (ManagedContextUtils.clearOwner(owner)) { ManagedThreadLocal.reset(); } } }  @Override void registerListener(final ManagedContextListener<?> listener); @Override void unregisterListener(final ManagedContextListener<?> listener); @Override void runWithContext(final Runnable run); @Override T callWithContext(final Callable<T> callable); List<ManagedContextListener<?>> getListeners(); void setListeners(final List<ManagedContextListener<?>> listeners);  }