DefaultRetryable implements Retryable<T> { public T executeWith(RetryExecutor executor) { if (executor == null) { try { return this.call(); } catch (Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw new RuntimeException(e); } } try { return executor.runInterruptible(this); } catch (RetryGiveupException e) { final Exception cause = e.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } throw new RuntimeException(cause); } catch (InterruptedException e) { throw new RuntimeException(e); } } DefaultRetryable(String operationName);  DefaultRetryable(String operationName, Callable<T> callable);  DefaultRetryable();  DefaultRetryable(Callable<T> callable); @Override T call(); @Override boolean isRetryableException(Exception exception); @Override void onRetry(Exception exception, int retryCount, int retryLimit, int retryWait); @Override void onGiveup(Exception firstException, Exception lastException); T executeWith(RetryExecutor executor); T executeWithCheckedException(RetryExecutor executor,
                                                               Class<X> propagateAsIsException);  }
@Test(expected = Deny.class) @SuppressWarnings("unchecked") public void execute_should_unwrap_RetryGiveupException() throws Exception { new DefaultRetryable(Deny.until(4)) .executeWith(retryExecutorBuilder().withRetryLimit(3).build()); }
@Test(expected = RuntimeException.class) @SuppressWarnings("unchecked") public void execute_should_unwrap_RetryGiveupException_but_rewrap_checked_exception_in_a_RuntimeException() { new DefaultRetryable(Deny.until(4).with(new Exception("A checked exception"))) .executeWith(retryExecutorBuilder().withRetryLimit(3).build()); }
@Test(expected = IllegalStateException.class) public void execute_without_an_implementation_should_throw_an_IllegalStateException() { new DefaultRetryable().executeWith(retryExecutorBuilder().build()); }