001/*
002 * Copyright 2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.springframework.batch.core.jsr.job.flow.support.state;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.List;
021
022import org.springframework.batch.core.JobExecution;
023import org.springframework.batch.core.job.flow.Flow;
024import org.springframework.batch.core.job.flow.FlowExecution;
025import org.springframework.batch.core.job.flow.FlowExecutionStatus;
026import org.springframework.batch.core.job.flow.FlowExecutor;
027import org.springframework.batch.core.jsr.job.flow.support.JsrFlow;
028
029/**
030 * JSR-352 states that artifacts cannot set the ExitStatus from within a split for a job.  Because
031 * of this, this state will reset the exit status once the flows have completed (prior to aggregation
032 * of the results).
033 *
034 * @author Michael Minella
035 * @since 3.0
036 */
037public class JsrSplitState extends org.springframework.batch.core.job.flow.support.state.SplitState {
038
039        /**
040         * @param flows {@link Flow}s to be executed in parallel
041         * @param name the name to be associated with the split state.
042         */
043        public JsrSplitState(Collection<Flow> flows, String name) {
044                super(flows, name);
045        }
046
047        /**
048         * Resets the {@link JobExecution}'s exit status before aggregating the results of the flows within
049         * the split.
050         *
051         * @param results the {@link FlowExecution}s from each of the flows executed within this split
052         * @param executor the {@link FlowExecutor} used to execute the flows
053         */
054        @Override
055        protected FlowExecutionStatus doAggregation(Collection<FlowExecution> results, FlowExecutor executor) {
056                List<String> stepNames = new ArrayList<String>();
057
058                for (Flow curFlow : getFlows()) {
059                        JsrFlow flow = (JsrFlow) curFlow;
060                        if(flow.getMostRecentStepName() != null) {
061                                stepNames.add(flow.getMostRecentStepName());
062                        }
063                }
064
065                if(!stepNames.isEmpty()) {
066                        executor.getJobExecution().getExecutionContext().put("batch.lastSteps", stepNames);
067                }
068
069                executor.getJobExecution().setExitStatus(null);
070
071                return super.doAggregation(results, executor);
072        }
073}