public ExecutionStatus doExecutionLoop() {

		final String methodName = "doExecutionLoop";
		
		try {
			currentExecutionElement = modelNavigator.getFirstExecutionElement(jobExecution.getRestartOn());
		} catch (IllegalTransitionException e) {
			String errorMsg = "Could not transition to first execution element within job.";
			logger.warning(errorMsg);
			throw new IllegalArgumentException(errorMsg, e);
		}

		logger.fine("First execution element = " + currentExecutionElement.getId());

		while (true) {

			if (jobContext.getBatchStatus().equals(BatchStatus.STOPPING)) {
				logger.fine(methodName + " Exiting execution loop as job is now in stopping state.");
				return new ExecutionStatus(ExtendedBatchStatus.JOB_OPERATOR_STOPPING);
			}
			
			IExecutionElementController currentElementController = getNextElementController();
			currentStoppableElementController = currentElementController;
			
			ExecutionStatus status = currentElementController.execute();

			// Nothing special for decision or step except to get exit status.  For flow and split we want to bubble up though.
			if ((currentExecutionElement instanceof Split) || (currentExecutionElement instanceof Flow)) {
				// Exit status and restartOn should both be in the job context.
				if (!status.getExtendedBatchStatus().equals(ExtendedBatchStatus.NORMAL_COMPLETION)) {
					logger.fine("Breaking out of loop with return status = " + status.getExtendedBatchStatus().name());
					return status;
				}
			} 

			// Seems like this should only happen if an Error is thrown at the step level, since normally a step-level
			// exception is caught and the fact that it was thrown capture in the ExecutionStatus
			if (jobContext.getBatchStatus().equals(BatchStatus.FAILED)) {
				String errorMsg = "Sub-execution returned its own BatchStatus of FAILED.  Deal with this by throwing exception to the next layer.";
				logger.warning(errorMsg);
				throw new BatchContainerRuntimeException(errorMsg);
			}

			// set the execution element controller to null so we don't try to call stop on it after the element has finished executing
			currentStoppableElementController = null;
			
			logger.fine("Done executing element=" + currentExecutionElement.getId() + ", exitStatus=" + status.getExitStatus());

			if (jobContext.getBatchStatus().equals(BatchStatus.STOPPING)) {
				logger.fine(methodName + " Exiting as job has been stopped");
				return new ExecutionStatus(ExtendedBatchStatus.JOB_OPERATOR_STOPPING);
			}

			Transition nextTransition = null;
			try {
				nextTransition = modelNavigator.getNextTransition(currentExecutionElement, status);
			} catch (IllegalTransitionException e) {
				String errorMsg = "Problem transitioning to next execution element.";
				logger.warning(errorMsg);
				throw new BatchContainerRuntimeException(errorMsg, e);
			} 

			//
			// We will find ourselves in one of four states now.  
			// 
			// 1. Finished transitioning after a normal execution, but nothing to do 'next'.
			// 2. We just executed a step which through an exception, but didn't match a transition element.
			// 3. We are going to 'next' to another execution element (and jump back to the top of this '
			//    'while'-loop.
			// 4. We matched a terminating transition element (<end>, <stop> or <fail).
			//
			
			// 1.
			if (nextTransition.isFinishedTransitioning()) {
				logger.fine(methodName + "No next execution element, and no transition element found either.  Looks like we're done and ready for COMPLETED state.");
				this.stepExecIds =  currentElementController.getLastRunStepExecutions();
				// Consider just passing the last 'status' back, but let's unwrap the exit status and pass a new NORMAL_COMPLETION
				// status back instead.
				return new ExecutionStatus(ExtendedBatchStatus.NORMAL_COMPLETION, status.getExitStatus());
			// 2.
			} else if (nextTransition.noTransitionElementMatchedAfterException()) {
				return new ExecutionStatus(ExtendedBatchStatus.EXCEPTION_THROWN, status.getExitStatus());
			// 3.
			} else if (nextTransition.getNextExecutionElement() != null) {
				// hold on to the previous execution element for the decider
				// we need it because we need to inject the context of the
				// previous execution element into the decider
				previousExecutionElement = currentExecutionElement;
				previousElementController = currentElementController;
				currentExecutionElement = nextTransition.getNextExecutionElement();
			// 4.
			} else if (nextTransition.getTransitionElement() != null) {
				ExecutionStatus terminatingStatus = handleTerminatingTransitionElement(nextTransition.getTransitionElement());
				logger.finer(methodName + " , Breaking out of execution loop after processing terminating transition element.");
				return terminatingStatus;
			} else {
				throw new IllegalStateException("Not sure how we'd end up in this state...aborting rather than looping.");
			}
		}
	}
public ExecutionStatus doExecutionLoop ( ) { final String methodName = "doExecutionLoop" ; try { currentExecutionElement = modelNavigator . getFirstExecutionElement ( jobExecution . getRestartOn ( ) ) ; } catch ( IllegalTransitionException e ) { String errorMsg = "Could not transition to first execution element within job." ; logger . warning ( errorMsg ) ; throw new IllegalArgumentException ( errorMsg , e ) ; } logger . fine ( "First execution element = " + currentExecutionElement . getId ( ) ) ; while ( true ) { if ( jobContext . getBatchStatus ( ) . equals ( BatchStatus . STOPPING ) ) { logger . fine ( methodName + " Exiting execution loop as job is now in stopping state." ) ; return new ExecutionStatus ( ExtendedBatchStatus . JOB_OPERATOR_STOPPING ) ; } IExecutionElementController currentElementController = getNextElementController ( ) ; currentStoppableElementController = currentElementController ; ExecutionStatus status = currentElementController . execute ( ) ; if ( ( currentExecutionElement instanceof Split ) || ( currentExecutionElement instanceof Flow ) ) { if ( ! status . getExtendedBatchStatus ( ) . equals ( ExtendedBatchStatus . NORMAL_COMPLETION ) ) { logger . fine ( "Breaking out of loop with return status = " + status . getExtendedBatchStatus ( ) . name ( ) ) ; return status ; } } if ( jobContext . getBatchStatus ( ) . equals ( BatchStatus . FAILED ) ) { String errorMsg = "Sub-execution returned its own BatchStatus of FAILED.  Deal with this by throwing exception to the next layer." ; logger . warning ( errorMsg ) ; throw new BatchContainerRuntimeException ( errorMsg ) ; } currentStoppableElementController = null ; logger . fine ( "Done executing element=" + currentExecutionElement . getId ( ) + ", exitStatus=" + status . getExitStatus ( ) ) ; if ( jobContext . getBatchStatus ( ) . equals ( BatchStatus . STOPPING ) ) { logger . fine ( methodName + " Exiting as job has been stopped" ) ; return new ExecutionStatus ( ExtendedBatchStatus . JOB_OPERATOR_STOPPING ) ; } Transition nextTransition = null ; try { nextTransition = modelNavigator . getNextTransition ( currentExecutionElement , status ) ; } catch ( IllegalTransitionException e ) { String errorMsg = "Problem transitioning to next execution element." ; logger . warning ( errorMsg ) ; throw new BatchContainerRuntimeException ( errorMsg , e ) ; } if ( nextTransition . isFinishedTransitioning ( ) ) { logger . fine ( methodName + "No next execution element, and no transition element found either.  Looks like we're done and ready for COMPLETED state." ) ; this . stepExecIds = currentElementController . getLastRunStepExecutions ( ) ; return new ExecutionStatus ( ExtendedBatchStatus . NORMAL_COMPLETION , status . getExitStatus ( ) ) ; } else if ( nextTransition . noTransitionElementMatchedAfterException ( ) ) { return new ExecutionStatus ( ExtendedBatchStatus . EXCEPTION_THROWN , status . getExitStatus ( ) ) ; } else if ( nextTransition . getNextExecutionElement ( ) != null ) { previousExecutionElement = currentExecutionElement ; previousElementController = currentElementController ; currentExecutionElement = nextTransition . getNextExecutionElement ( ) ; } else if ( nextTransition . getTransitionElement ( ) != null ) { ExecutionStatus terminatingStatus = handleTerminatingTransitionElement ( nextTransition . getTransitionElement ( ) ) ; logger . finer ( methodName + " , Breaking out of execution loop after processing terminating transition element." ) ; return terminatingStatus ; } else { throw new IllegalStateException ( "Not sure how we'd end up in this state...aborting rather than looping." ) ; } } }
Used for job and flow.
@return