001/* 002 * Copyright 2006-2013 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.flow.support.state; 018 019import org.springframework.batch.core.BatchStatus; 020import org.springframework.batch.core.StepExecution; 021import org.springframework.batch.core.job.flow.FlowExecutionStatus; 022import org.springframework.batch.core.job.flow.FlowExecutor; 023import org.springframework.batch.core.job.flow.State; 024 025/** 026 * {@link State} implementation for ending a job if it is in progress and 027 * continuing if just starting. 028 * 029 * @author Dave Syer 030 * @since 2.0 031 */ 032public class EndState extends AbstractState { 033 034 private final FlowExecutionStatus status; 035 036 private final boolean abandon; 037 038 private final String code; 039 040 /** 041 * @param status The {@link FlowExecutionStatus} to end with 042 * @param name The name of the state 043 */ 044 public EndState(FlowExecutionStatus status, String name) { 045 this(status, status.getName(), name); 046 } 047 048 /** 049 * @param status The {@link FlowExecutionStatus} to end with 050 * @param name The name of the state 051 * @param code The exit status to save 052 */ 053 public EndState(FlowExecutionStatus status, String code, String name) { 054 this(status, code, name, false); 055 } 056 057 /** 058 * @param status The {@link FlowExecutionStatus} to end with 059 * @param name The name of the state 060 * @param code The exit status to save 061 * @param abandon flag to indicate that previous step execution can be 062 * marked as abandoned (if there is one) 063 * 064 */ 065 public EndState(FlowExecutionStatus status, String code, String name, boolean abandon) { 066 super(name); 067 this.status = status; 068 this.code = code; 069 this.abandon = abandon; 070 } 071 072 protected FlowExecutionStatus getStatus() { 073 return this.status; 074 } 075 076 protected boolean isAbandon() { 077 return this.abandon; 078 } 079 080 protected String getCode() { 081 return this.code; 082 } 083 084 /** 085 * Return the {@link FlowExecutionStatus} stored. 086 * 087 * @see State#handle(FlowExecutor) 088 */ 089 @Override 090 public FlowExecutionStatus handle(FlowExecutor executor) throws Exception { 091 092 synchronized (executor) { 093 094 // Special case. If the last step execution could not complete we 095 // are in an unknown state (possibly unrecoverable). 096 StepExecution stepExecution = executor.getStepExecution(); 097 if (stepExecution != null && executor.getStepExecution().getStatus() == BatchStatus.UNKNOWN) { 098 return FlowExecutionStatus.UNKNOWN; 099 } 100 101 if (status.isStop()) { 102 if (!executor.isRestart()) { 103 /* 104 * If there are step executions, then we are not at the 105 * beginning of a restart. 106 */ 107 if (abandon) { 108 /* 109 * Only if instructed to do so, upgrade the status of 110 * last step execution so it is not replayed on a 111 * restart... 112 */ 113 executor.abandonStepExecution(); 114 } 115 } 116 else { 117 /* 118 * If we are a stop state and we got this far then it must 119 * be a restart, so return COMPLETED. 120 */ 121 return FlowExecutionStatus.COMPLETED; 122 } 123 } 124 125 setExitStatus(executor, code); 126 127 return status; 128 129 } 130 } 131 132 /** 133 * Performs any logic to update the exit status for the current flow. 134 * 135 * @param executor {@link FlowExecutor} for the current flow 136 * @param code The exit status to save 137 */ 138 protected void setExitStatus(FlowExecutor executor, String code) { 139 executor.addExitStatus(code); 140 } 141 142 /* 143 * (non-Javadoc) 144 * 145 * @see org.springframework.batch.core.job.flow.State#isEndState() 146 */ 147 @Override 148 public boolean isEndState() { 149 return !status.isStop(); 150 } 151 152 /* 153 * (non-Javadoc) 154 * 155 * @see java.lang.Object#toString() 156 */ 157 @Override 158 public String toString() { 159 return super.toString() + " status=[" + status + "]"; 160 } 161}