Example usage for org.springframework.batch.repeat RepeatContext close

List of usage examples for org.springframework.batch.repeat RepeatContext close

Introduction

In this page you can find the example usage for org.springframework.batch.repeat RepeatContext close.

Prototype

void close();

Source Link

Document

Allow resources to be cleared, especially in destruction callbacks.

Usage

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

/**
 * Internal convenience method to loop over interceptors and batch
 * callbacks./* w  w w . j ava  2s  . c  o  m*/
 * 
 * @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;

}