1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.batch.core;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.concurrent.CopyOnWriteArrayList;
29 import java.util.concurrent.CopyOnWriteArraySet;
30
31 import org.springframework.batch.item.ExecutionContext;
32
33
34
35
36
37
38
39 public class JobExecution extends Entity {
40
41 private JobInstance jobInstance;
42
43 private volatile Collection<StepExecution> stepExecutions = new CopyOnWriteArraySet<StepExecution>();
44
45 private volatile BatchStatus status = BatchStatus.STARTING;
46
47 private volatile Date startTime = null;
48
49 private volatile Date createTime = new Date(System.currentTimeMillis());
50
51 private volatile Date endTime = null;
52
53 private volatile Date lastUpdated = null;
54
55 private volatile ExitStatus exitStatus = ExitStatus.UNKNOWN;
56
57 private volatile ExecutionContext executionContext = new ExecutionContext();
58
59 private transient volatile List<Throwable> failureExceptions = new CopyOnWriteArrayList<Throwable>();
60
61
62
63
64
65
66
67 public JobExecution(JobInstance job, Long id) {
68 super(id);
69 this.jobInstance = job;
70 }
71
72
73
74
75
76
77 public JobExecution(JobInstance job) {
78 this(job, null);
79 }
80
81 public JobExecution(Long id) {
82 super(id);
83 }
84
85 public Date getEndTime() {
86 return endTime;
87 }
88
89 public void setJobInstance(JobInstance jobInstance) {
90 this.jobInstance = jobInstance;
91 }
92
93 public void setEndTime(Date endTime) {
94 this.endTime = endTime;
95 }
96
97 public Date getStartTime() {
98 return startTime;
99 }
100
101 public void setStartTime(Date startTime) {
102 this.startTime = startTime;
103 }
104
105 public BatchStatus getStatus() {
106 return status;
107 }
108
109
110
111
112
113
114 public void setStatus(BatchStatus status) {
115 this.status = status;
116 }
117
118
119
120
121
122
123
124
125 public void upgradeStatus(BatchStatus status) {
126 this.status = this.status.upgradeTo(status);
127 }
128
129
130
131
132
133
134
135 public Long getJobId() {
136 if (jobInstance != null) {
137 return jobInstance.getId();
138 }
139 return null;
140 }
141
142
143
144
145 public void setExitStatus(ExitStatus exitStatus) {
146 this.exitStatus = exitStatus;
147 }
148
149
150
151
152 public ExitStatus getExitStatus() {
153 return exitStatus;
154 }
155
156
157
158
159 public JobInstance getJobInstance() {
160 return jobInstance;
161 }
162
163
164
165
166
167
168 public Collection<StepExecution> getStepExecutions() {
169 return Collections.unmodifiableList(new ArrayList<StepExecution>(stepExecutions));
170 }
171
172
173
174
175
176 public StepExecution createStepExecution(String stepName) {
177 StepExecution stepExecution = new StepExecution(stepName, this);
178 this.stepExecutions.add(stepExecution);
179 return stepExecution;
180 }
181
182
183
184
185
186
187
188 public boolean isRunning() {
189 return endTime == null;
190 }
191
192
193
194
195
196
197 public boolean isStopping() {
198 return status == BatchStatus.STOPPING;
199 }
200
201
202
203
204
205
206 public void stop() {
207 for (StepExecution stepExecution : stepExecutions) {
208 stepExecution.setTerminateOnly();
209 }
210 status = BatchStatus.STOPPING;
211 }
212
213
214
215
216
217
218 public void setExecutionContext(ExecutionContext executionContext) {
219 this.executionContext = executionContext;
220 }
221
222
223
224
225
226
227
228 public ExecutionContext getExecutionContext() {
229 return executionContext;
230 }
231
232
233
234
235 public Date getCreateTime() {
236 return createTime;
237 }
238
239
240
241
242 public void setCreateTime(Date createTime) {
243 this.createTime = createTime;
244 }
245
246
247
248
249
250
251 void addStepExecution(StepExecution stepExecution) {
252 stepExecutions.add(stepExecution);
253 }
254
255
256
257
258
259
260
261 public Date getLastUpdated() {
262 return lastUpdated;
263 }
264
265
266
267
268
269
270 public void setLastUpdated(Date lastUpdated) {
271 this.lastUpdated = lastUpdated;
272 }
273
274 public List<Throwable> getFailureExceptions() {
275 return failureExceptions;
276 }
277
278
279
280
281
282
283 public synchronized void addFailureException(Throwable t) {
284 this.failureExceptions.add(t);
285 }
286
287
288
289
290
291
292
293
294 public synchronized List<Throwable> getAllFailureExceptions() {
295
296 Set<Throwable> allExceptions = new HashSet<Throwable>(failureExceptions);
297 for (StepExecution stepExecution : stepExecutions) {
298 allExceptions.addAll(stepExecution.getFailureExceptions());
299 }
300
301 return new ArrayList<Throwable>(allExceptions);
302 }
303
304
305
306
307
308 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
309 stream.defaultReadObject();
310 failureExceptions = new ArrayList<Throwable>();
311 }
312
313
314
315
316
317
318 public String toString() {
319 return super.toString()
320 + String.format(", startTime=%s, endTime=%s, lastUpdated=%s, status=%s, exitStatus=%s, job=[%s]",
321 startTime, endTime, lastUpdated, status, exitStatus, jobInstance);
322 }
323
324
325
326
327
328 public void addStepExecutions(List<StepExecution> stepExecutions) {
329 if (stepExecutions!=null) {
330 this.stepExecutions.removeAll(stepExecutions);
331 this.stepExecutions.addAll(stepExecutions);
332 }
333 }
334
335 }