diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/CompletionPolicy.java b/infrastructure/src/main/java/org/springframework/batch/repeat/CompletionPolicy.java index 84e9b314b..2aab88e0a 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/CompletionPolicy.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/CompletionPolicy.java @@ -41,7 +41,7 @@ public interface CompletionPolicy { * * @see #isComplete(RepeatContext) */ - boolean isComplete(RepeatContext context, Object result); + boolean isComplete(RepeatContext context, ExitStatus result); /** * Allow policy to signal completion according to internal state, without diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/exception/handler/ExceptionHandler.java b/infrastructure/src/main/java/org/springframework/batch/repeat/exception/handler/ExceptionHandler.java index e64271477..ab307ea11 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/exception/handler/ExceptionHandler.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/exception/handler/ExceptionHandler.java @@ -23,7 +23,7 @@ import org.springframework.batch.repeat.RepeatContext; * Handler to allow strategies for rethrowing exceptions. Normally a * {@link CompletionPolicy} will be used to decide whether to end a batch when * there is no exception, and the {@link ExceptionHandler} is used to signal an - * abnormal ending. An abnormal ending would normally result in an + * abnormal ending - an abnormal ending would result in an * {@link ExceptionHandler} throwing an exception. The caller will catch and * rethrow it if necessary. * @@ -34,7 +34,7 @@ public interface ExceptionHandler { /** * Deal with a Throwable during a batch. The input might be - * RuntimeExceptions or other unchecked exceptions. + * RuntimeException or other unchecked exceptions. * * @param context * the current {@link RepeatContext}. Can be used to store state diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompletionPolicySupport.java b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompletionPolicySupport.java index ca85cad30..246cc2d97 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompletionPolicySupport.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompletionPolicySupport.java @@ -16,6 +16,7 @@ package org.springframework.batch.repeat.policy; +import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.CompletionPolicy; import org.springframework.batch.repeat.context.RepeatContextSupport; @@ -32,9 +33,9 @@ public class CompletionPolicySupport implements CompletionPolicy { * Delegate to {@link #isComplete(RepeatContext)}. * * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext, - * java.lang.Object) + * ExitStatus) */ - public boolean isComplete(RepeatContext context, Object result) { + public boolean isComplete(RepeatContext context, ExitStatus result) { return isComplete(context); } diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicy.java b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicy.java index 6d2d70095..bb76fd702 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicy.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicy.java @@ -19,6 +19,7 @@ package org.springframework.batch.repeat.policy; import java.util.ArrayList; import java.util.List; +import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.CompletionPolicy; import org.springframework.batch.repeat.context.RepeatContextSupport; @@ -47,9 +48,9 @@ public class CompositeCompletionPolicy implements CompletionPolicy { * This policy is complete if any of the composed policies is complete. * * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext, - * java.lang.Object) + * ExitStatus) */ - public boolean isComplete(RepeatContext context, Object result) { + public boolean isComplete(RepeatContext context, ExitStatus result) { RepeatContext[] contexts = ((CompositeBatchContext) context).contexts; CompletionPolicy[] policies = ((CompositeBatchContext) context).policies; for (int i = 0; i < policies.length; i++) { diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/DefaultResultCompletionPolicy.java b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/DefaultResultCompletionPolicy.java index 1342eb2c5..e3c05afd3 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/DefaultResultCompletionPolicy.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/DefaultResultCompletionPolicy.java @@ -22,8 +22,8 @@ import org.springframework.batch.repeat.ExitStatus; /** * Very simple {@link CompletionPolicy} that bases its decision on the result of - * a batch operation. If the result is Boolean.FALSE, null or an instance of - * Throwable the batch is complete, otherwise not. + * a batch operation. If the result is null or not continuable according to the + * {@link ExitStatus} the batch is complete, otherwise not. * * @author Dave Syer * @@ -31,15 +31,14 @@ import org.springframework.batch.repeat.ExitStatus; public class DefaultResultCompletionPolicy extends CompletionPolicySupport { /** - * True if the result is null, a {@link ExitStatus} indicating completion, - * or an instance of Throwable. + * True if the result is null, or a {@link ExitStatus} indicating + * completion. * * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext, - * java.lang.Object) + * ExitStatus) */ - public boolean isComplete(RepeatContext context, Object result) { - return (result == null || (result instanceof Throwable) || (result instanceof ExitStatus && !((ExitStatus) result) - .isContinuable())); + public boolean isComplete(RepeatContext context, ExitStatus result) { + return (result == null || !result.isContinuable()); } /** diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicy.java b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicy.java index a550c34b0..ef418dfaf 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicy.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicy.java @@ -16,6 +16,7 @@ package org.springframework.batch.repeat.policy; +import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.context.RepeatContextSupport; import org.springframework.batch.repeat.support.RepeatTemplate; @@ -62,11 +63,11 @@ public class SimpleCompletionPolicy extends DefaultResultCompletionPolicy { * Terminate if the chunk size has been reached, or the result is null. * * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(RepeatContext, - * Object) + * ExitStatus) * @throws Exception (normally terminating the batch) if the result is * itself an exception. */ - public boolean isComplete(RepeatContext context, Object result) { + public boolean isComplete(RepeatContext context, ExitStatus result) { return super.isComplete(context, result) || ((SimpleTerminationContext) context).isComplete(); } diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java b/infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java index d8f1e236a..d51618f16 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/support/RepeatTemplate.java @@ -207,7 +207,7 @@ public class RepeatTemplate implements RepeatOperations { // continuing try { - + for (int i = interceptors.length; i-- > 0;) { RepeatInterceptor interceptor = interceptors[i]; interceptor.onError(context, throwable); @@ -218,16 +218,18 @@ public class RepeatTemplate implements RepeatOperations { + interceptors.length + ")", throwable); } - exceptionHandler.handleException(context, - throwable); - + exceptionHandler + .handleException(context, throwable); + } catch (Throwable handled) { throwables.add(handled); } } // N.B. the order may be important here: - if (isComplete(context, result) || isMarkedComplete(context) || !throwables.isEmpty()) { + if (isComplete(context, result) + || isMarkedComplete(context) + || !throwables.isEmpty()) { running = false; } } @@ -280,8 +282,10 @@ public class RepeatTemplate implements RepeatOperations { private static Exception rethrow(Throwable next) throws RuntimeException { if (next instanceof RuntimeException) { throw (RuntimeException) next; - }; - throw new RepeatException("Rethrowing exception that is no RuntimeException.", next); + } + ; + throw new RepeatException( + "Rethrowing exception that is no RuntimeException.", next); } /** @@ -314,7 +318,8 @@ public class RepeatTemplate implements RepeatOperations { * @see {@link #isComplete(RepeatContext)} */ protected ExitStatus getNextResult(RepeatContext context, - RepeatCallback callback, RepeatInternalState state) throws Throwable { + RepeatCallback callback, RepeatInternalState state) + throws Throwable { try { update(context); return callback.doInIteration(context); @@ -369,14 +374,12 @@ public class RepeatTemplate implements RepeatOperations { * the result of the callback to process. */ protected void executeAfterInterceptors(final RepeatContext context, - Object value) { + ExitStatus value) { // Don't re-throw exceptions here: let the exception handler deal with // that... - if (value != null - && ((value instanceof ExitStatus) - && ((ExitStatus) value).isContinuable() || (value instanceof Throwable))) { + if (value != null && value.isContinuable()) { for (int i = interceptors.length; i-- > 0;) { RepeatInterceptor interceptor = interceptors[i]; interceptor.after(context, value); @@ -390,9 +393,9 @@ public class RepeatTemplate implements RepeatOperations { * Delegate to the {@link CompletionPolicy}. * * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(RepeatContext, - * Object) + * ExitStatus) */ - public boolean isComplete(RepeatContext context, Object result) { + public boolean isComplete(RepeatContext context, ExitStatus result) { boolean complete = completionPolicy.isComplete(context, result); if (complete) { logger diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java b/infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java index 589330227..1518e973c 100644 --- a/infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java +++ b/infrastructure/src/main/java/org/springframework/batch/repeat/support/TaskExecutorRepeatTemplate.java @@ -167,8 +167,9 @@ public class TaskExecutorRepeatTemplate extends RepeatTemplate { if (value instanceof Throwable) { state.getThrowables().add(value); } else { - result = result && canContinue((ExitStatus) value); - executeAfterInterceptors(future.getContext(), value); + ExitStatus status = (ExitStatus) value; + result = result && canContinue(status); + executeAfterInterceptors(future.getContext(), status); } } diff --git a/infrastructure/src/test/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicyTests.java b/infrastructure/src/test/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicyTests.java index 797824bd2..00dfd55ea 100644 --- a/infrastructure/src/test/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicyTests.java +++ b/infrastructure/src/test/java/org/springframework/batch/repeat/policy/CompositeCompletionPolicyTests.java @@ -18,6 +18,7 @@ package org.springframework.batch.repeat.policy; import junit.framework.TestCase; +import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.CompletionPolicy; @@ -58,7 +59,7 @@ public class CompositeCompletionPolicyTests extends TestCase { CompositeCompletionPolicy policy = new CompositeCompletionPolicy(); policy.setPolicies(new CompletionPolicy[] { new MockCompletionPolicySupport(), new MockCompletionPolicySupport() { - public boolean isComplete(RepeatContext context, Object result) { + public boolean isComplete(RepeatContext context, ExitStatus result) { return true; } } }); diff --git a/infrastructure/src/test/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicyTests.java b/infrastructure/src/test/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicyTests.java index 942ef34d5..241a8fd77 100644 --- a/infrastructure/src/test/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicyTests.java +++ b/infrastructure/src/test/java/org/springframework/batch/repeat/policy/SimpleCompletionPolicyTests.java @@ -18,6 +18,7 @@ package org.springframework.batch.repeat.policy; import junit.framework.TestCase; +import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatContext; public class SimpleCompletionPolicyTests extends TestCase { @@ -26,7 +27,7 @@ public class SimpleCompletionPolicyTests extends TestCase { RepeatContext context; - Object dummy = "foo"; + ExitStatus dummy = ExitStatus.CONTINUABLE; protected void setUp() throws Exception { super.setUp(); @@ -60,17 +61,6 @@ public class SimpleCompletionPolicyTests extends TestCase { assertTrue(policy.isComplete(context, null)); } - public void testTerminationAfterException() throws Exception { - policy.update(context); - try { - assertTrue(policy.isComplete(context, new IllegalStateException("foo"))); - } - catch (IllegalStateException e) { - assertEquals("foo", e.getMessage()); - fail("Unxpected IllegalStateException"); - } - } - public void testReset() throws Exception { policy.setChunkSize(2); policy.update(context); diff --git a/infrastructure/src/test/java/org/springframework/batch/repeat/policy/TimeoutCompletionPolicyTests.java b/infrastructure/src/test/java/org/springframework/batch/repeat/policy/TimeoutCompletionPolicyTests.java index 80bd884cf..453246142 100644 --- a/infrastructure/src/test/java/org/springframework/batch/repeat/policy/TimeoutCompletionPolicyTests.java +++ b/infrastructure/src/test/java/org/springframework/batch/repeat/policy/TimeoutCompletionPolicyTests.java @@ -47,46 +47,4 @@ public class TimeoutCompletionPolicyTests extends TestCase { assertTrue(policy.isComplete(context)); } - public void testException() throws Exception { - TimeoutTerminationPolicy policy = new TimeoutTerminationPolicy(); - RepeatContext context = policy.start(null); - assertFalse(policy.isComplete(context)); - try { - policy.isComplete(context, new RuntimeException("foo")); - } - catch (RuntimeException e) { - // expected - assertEquals("foo", e.getMessage()); - } - assertFalse(policy.isComplete(context)); - } - - public void testError() throws Exception { - TimeoutTerminationPolicy policy = new TimeoutTerminationPolicy(); - RepeatContext context = policy.start(null); - assertFalse(policy.isComplete(context)); - try { - policy.isComplete(context, new Error("foo")); - } - catch (Error e) { - // expected - assertEquals("foo", e.getMessage()); - } - assertFalse(policy.isComplete(context)); - } - - public void testThrowable() throws Exception { - TimeoutTerminationPolicy policy = new TimeoutTerminationPolicy(); - RepeatContext context = policy.start(null); - assertFalse(policy.isComplete(context)); - try { - policy.isComplete(context, new Throwable("foo")); - } - catch (Throwable e) { - // expected - assertEquals("foo", e.getCause().getMessage()); - } - assertFalse(policy.isComplete(context)); - } - }