1 /*
2 * Copyright 2006-2013 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.springframework.batch.core.job.flow.support.state;
18
19 import org.springframework.batch.core.BatchStatus;
20 import org.springframework.batch.core.StepExecution;
21 import org.springframework.batch.core.job.flow.FlowExecutionStatus;
22 import org.springframework.batch.core.job.flow.FlowExecutor;
23 import org.springframework.batch.core.job.flow.State;
24
25 /**
26 * {@link State} implementation for ending a job if it is in progress and
27 * continuing if just starting.
28 *
29 * @author Dave Syer
30 * @since 2.0
31 */
32 public class EndState extends AbstractState {
33
34 private final FlowExecutionStatus status;
35
36 private final boolean abandon;
37
38 private final String code;
39
40 /**
41 * @param status The {@link FlowExecutionStatus} to end with
42 * @param name The name of the state
43 */
44 public EndState(FlowExecutionStatus status, String name) {
45 this(status, status.getName(), name);
46 }
47
48 /**
49 * @param status The {@link FlowExecutionStatus} to end with
50 * @param name The name of the state
51 */
52 public EndState(FlowExecutionStatus status, String code, String name) {
53 this(status, code, name, false);
54 }
55
56 /**
57 * @param status The {@link FlowExecutionStatus} to end with
58 * @param name The name of the state
59 * @param abandon flag to indicate that previous step execution can be
60 * marked as abandoned (if there is one)
61 *
62 */
63 public EndState(FlowExecutionStatus status, String code, String name, boolean abandon) {
64 super(name);
65 this.status = status;
66 this.code = code;
67 this.abandon = abandon;
68 }
69
70 /**
71 * Return the {@link FlowExecutionStatus} stored.
72 *
73 * @see State#handle(FlowExecutor)
74 */
75 @Override
76 public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
77
78 synchronized (executor) {
79
80 // Special case. If the last step execution could not complete we
81 // are in an unknown state (possibly unrecoverable).
82 StepExecution stepExecution = executor.getStepExecution();
83 if (stepExecution != null && executor.getStepExecution().getStatus() == BatchStatus.UNKNOWN) {
84 return FlowExecutionStatus.UNKNOWN;
85 }
86
87 if (status.isStop()) {
88 if (!executor.isRestart()) {
89 /*
90 * If there are step executions, then we are not at the
91 * beginning of a restart.
92 */
93 if (abandon) {
94 /*
95 * Only if instructed to do so, upgrade the status of
96 * last step execution so it is not replayed on a
97 * restart...
98 */
99 executor.abandonStepExecution();
100 }
101 }
102 else {
103 /*
104 * If we are a stop state and we got this far then it must
105 * be a restart, so return COMPLETED.
106 */
107 return FlowExecutionStatus.COMPLETED;
108 }
109 }
110
111 executor.addExitStatus(code);
112 return status;
113
114 }
115 }
116
117 /*
118 * (non-Javadoc)
119 *
120 * @see org.springframework.batch.core.job.flow.State#isEndState()
121 */
122 @Override
123 public boolean isEndState() {
124 return !status.isStop();
125 }
126
127 /*
128 * (non-Javadoc)
129 *
130 * @see java.lang.Object#toString()
131 */
132 @Override
133 public String toString() {
134 return super.toString() + " status=[" + status + "]";
135 }
136 }