001/* 002 * Copyright 2006-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 */ 016 017package org.springframework.batch.core.job; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.List; 022 023import org.springframework.batch.core.BatchStatus; 024import org.springframework.batch.core.Job; 025import org.springframework.batch.core.JobExecution; 026import org.springframework.batch.core.JobInterruptedException; 027import org.springframework.batch.core.StartLimitExceededException; 028import org.springframework.batch.core.Step; 029import org.springframework.batch.core.StepExecution; 030import org.springframework.batch.core.repository.JobRestartException; 031import org.springframework.batch.core.step.StepLocator; 032 033/** 034 * Simple implementation of {@link Job} interface providing the ability to run a 035 * {@link JobExecution}. Sequentially executes a job by iterating through its 036 * list of steps. Any {@link Step} that fails will fail the job. The job is 037 * considered complete when all steps have been executed. 038 * 039 * @author Lucas Ward 040 * @author Dave Syer 041 * @author Michael Minella 042 */ 043public class SimpleJob extends AbstractJob { 044 045 private List<Step> steps = new ArrayList<Step>(); 046 047 /** 048 * Default constructor for job with null name 049 */ 050 public SimpleJob() { 051 this(null); 052 } 053 054 /** 055 * @param name the job name. 056 */ 057 public SimpleJob(String name) { 058 super(name); 059 } 060 061 /** 062 * Public setter for the steps in this job. Overrides any calls to 063 * {@link #addStep(Step)}. 064 * 065 * @param steps the steps to execute 066 */ 067 public void setSteps(List<Step> steps) { 068 this.steps.clear(); 069 this.steps.addAll(steps); 070 } 071 072 /** 073 * Convenience method for clients to inspect the steps for this job. 074 * 075 * @return the step names for this job 076 */ 077 @Override 078 public Collection<String> getStepNames() { 079 List<String> names = new ArrayList<String>(); 080 for (Step step : steps) { 081 names.add(step.getName()); 082 083 if(step instanceof StepLocator) { 084 names.addAll(((StepLocator)step).getStepNames()); 085 } 086 } 087 return names; 088 } 089 090 /** 091 * Convenience method for adding a single step to the job. 092 * 093 * @param step a {@link Step} to add 094 */ 095 public void addStep(Step step) { 096 this.steps.add(step); 097 } 098 099 /* 100 * (non-Javadoc) 101 * 102 * @see 103 * org.springframework.batch.core.job.AbstractJob#getStep(java.lang.String) 104 */ 105 @Override 106 public Step getStep(String stepName) { 107 for (Step step : this.steps) { 108 if (step.getName().equals(stepName)) { 109 return step; 110 } else if(step instanceof StepLocator) { 111 Step result = ((StepLocator)step).getStep(stepName); 112 if(result != null) { 113 return result; 114 } 115 } 116 } 117 return null; 118 } 119 120 /** 121 * Handler of steps sequentially as provided, checking each one for success 122 * before moving to the next. Returns the last {@link StepExecution} 123 * successfully processed if it exists, and null if none were processed. 124 * 125 * @param execution the current {@link JobExecution} 126 * 127 * @see AbstractJob#handleStep(Step, JobExecution) 128 */ 129 @Override 130 protected void doExecute(JobExecution execution) throws JobInterruptedException, JobRestartException, 131 StartLimitExceededException { 132 133 StepExecution stepExecution = null; 134 for (Step step : steps) { 135 stepExecution = handleStep(step, execution); 136 if (stepExecution.getStatus() != BatchStatus.COMPLETED) { 137 // 138 // Terminate the job if a step fails 139 // 140 break; 141 } 142 } 143 144 // 145 // Update the job status to be the same as the last step 146 // 147 if (stepExecution != null) { 148 if (logger.isDebugEnabled()) { 149 logger.debug("Upgrading JobExecution status: " + stepExecution); 150 } 151 execution.upgradeStatus(stepExecution.getStatus()); 152 execution.setExitStatus(stepExecution.getExitStatus()); 153 } 154 } 155 156}