Example usage for org.springframework.batch.repeat.support RepeatInternalState getThrowables

List of usage examples for org.springframework.batch.repeat.support RepeatInternalState getThrowables

Introduction

In this page you can find the example usage for org.springframework.batch.repeat.support RepeatInternalState getThrowables.

Prototype

Collection<Throwable> getThrowables();

Source Link

Document

Returns a mutable collection of exceptions that have occurred in the current repeat context.

Usage

From source file:org.springframework.batch.repeat.support.RepeatTemplate.java

/**
 * Internal convenience method to loop over interceptors and batch
 * callbacks./* ww  w.j a v a2  s .  c  om*/
 * 
 * @param callback the callback to process each element of the loop.
 * 
 * @return the aggregate of {@link RepeatTemplate#canContinue(RepeatStatus)}
 * for all the results from the callback.
 * 
 */
private RepeatStatus executeInternal(final RepeatCallback callback) {

    // Reset the termination policy if there is one...
    RepeatContext context = start();

    // Make sure if we are already marked complete before we start then no
    // processing takes place.
    boolean running = !isMarkedComplete(context);

    for (int i = 0; i < listeners.length; i++) {
        RepeatListener interceptor = listeners[i];
        interceptor.open(context);
        running = running && !isMarkedComplete(context);
        if (!running)
            break;
    }

    // Return value, default is to allow continued processing.
    RepeatStatus result = RepeatStatus.CONTINUABLE;

    RepeatInternalState state = createInternalState(context);
    // This is the list of exceptions thrown by all active callbacks
    Collection<Throwable> throwables = state.getThrowables();
    // Keep a separate list of exceptions we handled that need to be
    // rethrown
    Collection<Throwable> deferred = new ArrayList<Throwable>();

    try {

        while (running) {

            /*
             * Run the before interceptors here, not in the task executor so
             * that they all happen in the same thread - it's easier for
             * tracking batch status, amongst other things.
             */
            for (int i = 0; i < listeners.length; i++) {
                RepeatListener interceptor = listeners[i];
                interceptor.before(context);
                // Allow before interceptors to veto the batch by setting
                // flag.
                running = running && !isMarkedComplete(context);
            }

            // Check that we are still running (should always be true) ...
            if (running) {

                try {

                    result = getNextResult(context, callback, state);
                    executeAfterInterceptors(context, result);

                } catch (Throwable throwable) {
                    doHandle(throwable, context, deferred);
                }

                // N.B. the order may be important here:
                if (isComplete(context, result) || isMarkedComplete(context) || !deferred.isEmpty()) {
                    running = false;
                }

            }

        }

        result = result.and(waitForResults(state));
        for (Throwable throwable : throwables) {
            doHandle(throwable, context, deferred);
        }

        // Explicitly drop any references to internal state...
        state = null;

    }
    /*
     * No need for explicit catch here - if the business processing threw an
     * exception it was already handled by the helper methods. An exception
     * here is necessarily fatal.
     */
    finally {

        try {

            if (!deferred.isEmpty()) {
                Throwable throwable = deferred.iterator().next();
                if (logger.isDebugEnabled()) {
                    logger.debug("Handling fatal exception explicitly (rethrowing first of " + deferred.size()
                            + "): " + throwable.getClass().getName() + ": " + throwable.getMessage());
                }
                rethrow(throwable);
            }

        } finally {

            try {
                for (int i = listeners.length; i-- > 0;) {
                    RepeatListener interceptor = listeners[i];
                    interceptor.close(context);
                }
            } finally {
                context.close();
            }

        }

    }

    return result;

}