001/*
002 * Copyright 2013-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.partition;
017
018import org.springframework.batch.core.JobExecution;
019import org.springframework.batch.core.JobExecutionException;
020import org.springframework.batch.core.StepExecution;
021import org.springframework.batch.core.jsr.launch.JsrJobOperator;
022import org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter;
023import org.springframework.batch.core.repository.JobRepository;
024import org.springframework.batch.item.ExecutionContext;
025
026import java.util.Comparator;
027import java.util.Set;
028import java.util.TreeSet;
029
030/**
031 * Provides JSR-352 specific behavior for the splitting of {@link StepExecution}s.
032 *
033 * @author Michael Minella
034 * @since 3.0
035 */
036public class JsrStepExecutionSplitter extends SimpleStepExecutionSplitter {
037
038        private String stepName;
039        private JobRepository jobRepository;
040        private boolean restoreState;
041
042        public JsrStepExecutionSplitter(JobRepository jobRepository, boolean allowStartIfComplete, String stepName, boolean restoreState) {
043                super(jobRepository, allowStartIfComplete, stepName, null);
044                this.stepName = stepName;
045                this.jobRepository = jobRepository;
046                this.restoreState = restoreState;
047        }
048
049        @Override
050        public String getStepName() {
051                return this.stepName;
052        }
053
054        /**
055         * Returns the same number of {@link StepExecution}s as the gridSize specifies.  Each
056         * of the child StepExecutions will <em>not</em> be available via the {@link JsrJobOperator} per
057         * JSR-352.
058         *
059         * @see <a href="https://java.net/projects/jbatch/lists/public/archive/2013-10/message/10">https://java.net/projects/jbatch/lists/public/archive/2013-10/message/10</a>
060         */
061        @Override
062        public Set<StepExecution> split(StepExecution stepExecution, int gridSize)
063                        throws JobExecutionException {
064                Set<StepExecution> executions = new TreeSet<StepExecution>(new Comparator<StepExecution>() {
065
066                        @Override
067                        public int compare(StepExecution arg0, StepExecution arg1) {
068                                String r1 = "";
069                                String r2 = "";
070                                if (arg0 != null) {
071                                        r1 = arg0.getStepName();
072                                }
073                                if (arg1 != null) {
074                                        r2 = arg1.getStepName();
075                                }
076
077                                return r1.compareTo(r2);
078                        }
079                });
080                JobExecution jobExecution = stepExecution.getJobExecution();
081
082                for(int i = 0; i < gridSize; i++) {
083                        String stepName = this.stepName + ":partition" + i;
084                        JobExecution curJobExecution = new JobExecution(jobExecution);
085                        StepExecution curStepExecution = new StepExecution(stepName, curJobExecution);
086
087                        if(!restoreState || isStartable(curStepExecution, new ExecutionContext())) {
088                                executions.add(curStepExecution);
089                        }
090                }
091
092                jobRepository.addAll(executions);
093
094                return executions;
095        }
096}