diff --git a/core/src/main/java/org/springframework/batch/core/domain/JobExecution.java b/core/src/main/java/org/springframework/batch/core/domain/JobExecution.java
index f26da2841..bf364831f 100644
--- a/core/src/main/java/org/springframework/batch/core/domain/JobExecution.java
+++ b/core/src/main/java/org/springframework/batch/core/domain/JobExecution.java
@@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.HashSet;
import org.springframework.batch.core.runtime.JobIdentifier;
+import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatContext;
/**
@@ -45,7 +46,7 @@ public class JobExecution extends Entity {
private Timestamp endTime = null;
- private String exitCode = "";
+ private ExitStatus exitStatus = ExitStatus.UNKNOWN;
// Package private constructor for Hibernate
JobExecution() {
@@ -110,17 +111,17 @@ public class JobExecution extends Entity {
}
/**
- * @param exitCode
+ * @param exitStatus
*/
- public void setExitCode(String exitCode) {
- this.exitCode = exitCode;
+ public void setExitStatus(ExitStatus exitStatus) {
+ this.exitStatus = exitStatus;
}
/**
* @return the exitCode
*/
- public String getExitCode() {
- return exitCode;
+ public ExitStatus getExitStatus() {
+ return exitStatus;
}
/**
@@ -130,7 +131,7 @@ public class JobExecution extends Entity {
* be multiple active contexts.
*
* @return all the chunk contexts that have been registered and not
- * unregistered. A collection opf {@link RepeatContext} objects.
+ * unregistered. A collection of {@link RepeatContext} objects.
*/
public Collection getChunkContexts() {
synchronized (chunkContexts) {
diff --git a/core/src/main/java/org/springframework/batch/core/domain/StepExecution.java b/core/src/main/java/org/springframework/batch/core/domain/StepExecution.java
index 22509d766..dcbcd9b87 100644
--- a/core/src/main/java/org/springframework/batch/core/domain/StepExecution.java
+++ b/core/src/main/java/org/springframework/batch/core/domain/StepExecution.java
@@ -19,6 +19,8 @@ package org.springframework.batch.core.domain;
import java.sql.Timestamp;
import java.util.Properties;
+import org.springframework.batch.repeat.ExitStatus;
+
/**
* Batch domain object representation the execution of a step. Unlike
* JobExecution, there are four additional properties: luwCount, commitCount,
@@ -51,10 +53,8 @@ public class StepExecution extends Entity {
private Properties statistics = new Properties();
- private String exitCode = "";
+ private ExitStatus exitStatus = ExitStatus.UNKNOWN;
- private String exitDescription = "";
-
private Throwable exception;
/**
@@ -199,17 +199,17 @@ public class StepExecution extends Entity {
/**
- * @param exitCode
+ * @param exitStatus
*/
- public void setExitCode(String exitCode) {
- this.exitCode = exitCode;
+ public void setExitStatus(ExitStatus exitStatus) {
+ this.exitStatus = exitStatus;
}
/**
* @return the exitCode
*/
- public String getExitCode() {
- return exitCode;
+ public ExitStatus getExitStatus() {
+ return exitStatus;
}
public void setException(Throwable exception) {
@@ -219,14 +219,6 @@ public class StepExecution extends Entity {
public Throwable getException() {
return exception;
}
-
- public void setExitDescription(String exitDescription) {
- this.exitDescription = exitDescription;
- }
-
- public String getExitDescription() {
- return exitDescription;
- }
/**
* Accessor for the step governing this execution.
diff --git a/core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java b/core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java
index 6c54a8056..a1db22568 100644
--- a/core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java
+++ b/core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java
@@ -20,6 +20,7 @@ import java.sql.Timestamp;
import junit.framework.TestCase;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
+import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.context.RepeatContextSupport;
/**
@@ -75,12 +76,27 @@ public class JobExecutionTests extends TestCase {
}
/**
- * Test method for {@link org.springframework.batch.core.domain.JobExecution#getExitCode()}.
+ * Test method for {@link org.springframework.batch.core.domain.JobExecution#getJobId()}.
+ */
+ public void testGetJobIdForNullJob() {
+ execution = new JobExecution(null);
+ assertEquals(null, execution.getJobId());
+ }
+
+ /**
+ * Test method for {@link org.springframework.batch.core.domain.JobExecution#getJobId()}.
+ */
+ public void testGetJob() {
+ assertNotNull(execution.getJob());
+ }
+
+ /**
+ * Test method for {@link org.springframework.batch.core.domain.JobExecution#getExitStatus()}.
*/
public void testGetExitCode() {
- assertEquals("", execution.getExitCode());
- execution.setExitCode("23");
- assertEquals("23", execution.getExitCode());
+ assertEquals(ExitStatus.UNKNOWN, execution.getExitStatus());
+ execution.setExitStatus(new ExitStatus(true, "23"));
+ assertEquals("23", execution.getExitStatus().getExitCode());
}
public void testContextContainsInfo() throws Exception {
diff --git a/core/src/test/java/org/springframework/batch/core/domain/StepExecutionTests.java b/core/src/test/java/org/springframework/batch/core/domain/StepExecutionTests.java
index f8aab34c1..ab1387823 100644
--- a/core/src/test/java/org/springframework/batch/core/domain/StepExecutionTests.java
+++ b/core/src/test/java/org/springframework/batch/core/domain/StepExecutionTests.java
@@ -18,6 +18,8 @@ package org.springframework.batch.core.domain;
import java.sql.Timestamp;
import java.util.Properties;
+import org.springframework.batch.repeat.ExitStatus;
+
import junit.framework.TestCase;
/**
@@ -77,12 +79,12 @@ public class StepExecutionTests extends TestCase {
/**
* Test method for
- * {@link org.springframework.batch.core.domain.JobExecution#getExitCode()}.
+ * {@link org.springframework.batch.core.domain.JobExecution#getExitStatus()}.
*/
public void testGetExitCode() {
- assertEquals("", execution.getExitCode());
- execution.setExitCode("23");
- assertEquals("23", execution.getExitCode());
+ assertEquals(ExitStatus.UNKNOWN, execution.getExitStatus());
+ execution.setExitStatus(ExitStatus.FINISHED);
+ assertEquals(ExitStatus.FINISHED, execution.getExitStatus());
}
/**
diff --git a/dictionary.txt b/dictionary.txt
index 6cbf677cc..b05df35be 100644
--- a/dictionary.txt
+++ b/dictionary.txt
@@ -47,3 +47,4 @@ incrementer
hoc
unbind
tasklet
+bespoke
diff --git a/execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java b/execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java
index 4e4fe3f30..a5d185292 100644
--- a/execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java
+++ b/execution/src/main/java/org/springframework/batch/execution/job/DefaultJobExecutor.java
@@ -93,7 +93,7 @@ public class DefaultJobExecutor implements JobExecutor {
}
finally {
jobExecution.setEndTime(new Timestamp(System.currentTimeMillis()));
- jobExecution.setExitCode(status.getExitCode());
+ jobExecution.setExitStatus(status);
jobRepository.saveOrUpdate(jobExecution);
}
diff --git a/execution/src/main/java/org/springframework/batch/execution/repository/dao/ExitStatusUserType.java b/execution/src/main/java/org/springframework/batch/execution/repository/dao/ExitStatusUserType.java
new file mode 100644
index 000000000..bb043fe22
--- /dev/null
+++ b/execution/src/main/java/org/springframework/batch/execution/repository/dao/ExitStatusUserType.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2006-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.batch.execution.repository.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.HibernateException;
+import org.springframework.batch.repeat.ExitStatus;
+
+/**
+ * User type object to help Hibernate persist (@link {@link ExitStatus})
+ * objects. The continuable flag is mapped to a String with value Y/N.
+ *
+ * @author Dave Syer
+ *
+ */
+public class ExitStatusUserType extends ImmutableValueUserType {
+
+ /**
+ * Convert a result set to an {@link ExitStatus}.
+ *
+ * @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
+ */
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
+ throws HibernateException, SQLException {
+ boolean continuable = "Y".equals(rs.getString(names[0]));
+ String code = rs.getString(names[1]);
+ String message = rs.getString(names[2]);
+ return new ExitStatus(continuable, code, message);
+ }
+
+ /**
+ * Convert the value (as an {@link ExitStatus}) to the columns in the
+ * prepared statement.
+ *
+ * @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#nullSafeSet(java.sql.PreparedStatement,
+ * java.lang.Object, int)
+ */
+ public void nullSafeSet(PreparedStatement st, Object value, int index)
+ throws HibernateException, SQLException {
+ ExitStatus status = (ExitStatus) value;
+ st.setString(index, status.isContinuable() ? "Y" : "N");
+ st.setString(index + 1, status.getExitCode());
+ st.setString(index + 2, status.getExitDescription());
+ }
+
+ public Class returnedClass() {
+ return ExitStatus.class;
+ }
+
+ public int[] sqlTypes() {
+ return new int[] { Types.CHAR, Types.VARCHAR, Types.VARCHAR };
+ }
+
+}
diff --git a/execution/src/main/java/org/springframework/batch/execution/repository/dao/ImmutableValueUserType.java b/execution/src/main/java/org/springframework/batch/execution/repository/dao/ImmutableValueUserType.java
new file mode 100644
index 000000000..03af04085
--- /dev/null
+++ b/execution/src/main/java/org/springframework/batch/execution/repository/dao/ImmutableValueUserType.java
@@ -0,0 +1,62 @@
+package org.springframework.batch.execution.repository.dao;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.UserType;
+
+/**
+ * A base class for user types that map immutable values (objects that cannot be
+ * changed after construction and may be safely shared).
+ *
+ * @author Ben Hale
+ * @author Dave Syer
+ */
+public abstract class ImmutableValueUserType implements UserType {
+
+ public Object assemble(Serializable cached, Object owner)
+ throws HibernateException {
+ return cached;
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ public Serializable disassemble(Object value) throws HibernateException {
+ return (Serializable) value;
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ return x.equals(y);
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Object replace(Object original, Object target, Object owner)
+ throws HibernateException {
+ return original;
+ }
+
+ // subclasses must implement the following methods
+
+ public abstract Class returnedClass();
+
+ public abstract int[] sqlTypes();
+
+ public abstract Object nullSafeGet(ResultSet rs, String[] names,
+ Object owner) throws HibernateException, SQLException;
+
+ public abstract void nullSafeSet(PreparedStatement st, Object value,
+ int index) throws HibernateException, SQLException;
+
+}
diff --git a/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlJobDao.java b/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlJobDao.java
index 01c5ebb7e..35f5fc05f 100644
--- a/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlJobDao.java
+++ b/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlJobDao.java
@@ -26,6 +26,7 @@ import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.repository.NoSuchBatchDomainObjectException;
import org.springframework.batch.core.runtime.JobIdentifier;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
+import org.springframework.batch.repeat.ExitStatus;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
@@ -69,10 +70,10 @@ public class SqlJobDao implements JobDao, InitializingBean {
// Job Execution SqlStatements
private static final String UPDATE_JOB_EXECUTION = "UPDATE %PREFIX%JOB_EXECUTION set START_TIME = ?, END_TIME = ?, "
- + " STATUS = ?, EXIT_CODE = ? where ID = ?";
+ + " STATUS = ?, CONTINUABLE = ?, EXIT_CODE = ?, EXIT_MESSAGE = ? where ID = ?";
private static final String SAVE_JOB_EXECUTION = "INSERT into %PREFIX%JOB_EXECUTION(ID, JOB_ID, START_TIME, "
- + "END_TIME, STATUS, EXIT_CODE) values (?, ?, ?, ?, ?, ?)";
+ + "END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE) values (?, ?, ?, ?, ?, ?, ?, ?)";
private static final String CHECK_JOB_EXECUTION_EXISTS = "SELECT COUNT(*) FROM %PREFIX%JOB_EXECUTION WHERE ID=?";
@@ -187,7 +188,9 @@ public class SqlJobDao implements JobDao, InitializingBean {
Object[] parameters = new Object[] { jobExecution.getId(),
jobExecution.getJobId(), jobExecution.getStartTime(),
jobExecution.getEndTime(), jobExecution.getStatus().toString(),
- jobExecution.getExitCode() };
+ jobExecution.getExitStatus().isContinuable() ? "Y" : "N",
+ jobExecution.getExitStatus().getExitCode(),
+ jobExecution.getExitStatus().getExitDescription() };
jdbcTemplate.update(getSaveJobExecutionQuery(), parameters);
}
@@ -205,7 +208,10 @@ public class SqlJobDao implements JobDao, InitializingBean {
Object[] parameters = new Object[] { jobExecution.getStartTime(),
jobExecution.getEndTime(), jobExecution.getStatus().toString(),
- jobExecution.getExitCode(), jobExecution.getId() };
+ jobExecution.getExitStatus().isContinuable() ? "Y" : "N",
+ jobExecution.getExitStatus().getExitCode(),
+ jobExecution.getExitStatus().getExitDescription(),
+ jobExecution.getId() };
if (jobExecution.getId() == null) {
throw new IllegalArgumentException(
@@ -246,7 +252,8 @@ public class SqlJobDao implements JobDao, InitializingBean {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(job.getId(), "Job Id cannot be null.");
- return jdbcTemplate.query(getQuery(JobExecutionRowMapper.FIND_JOB_EXECUTIONS),
+ return jdbcTemplate.query(
+ getQuery(JobExecutionRowMapper.FIND_JOB_EXECUTIONS),
new Object[] { job.getId() }, new JobExecutionRowMapper(job));
}
@@ -366,16 +373,17 @@ public class SqlJobDao implements JobDao, InitializingBean {
/**
* Re-usable mapper for {@link JobExecution} instances.
+ *
* @author Dave Syer
- *
+ *
*/
public static class JobExecutionRowMapper implements RowMapper {
-
- public static final String FIND_JOB_EXECUTIONS = "SELECT ID, START_TIME, END_TIME, STATUS from %PREFIX%JOB_EXECUTION"
- + " where JOB_ID = ?";
- public static final String GET_JOB_EXECUTION = "SELECT ID, START_TIME, END_TIME, STATUS from %PREFIX%JOB_EXECUTION"
- + " where ID = ?";
+ public static final String FIND_JOB_EXECUTIONS = "SELECT ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION"
+ + " where JOB_ID = ?";
+
+ public static final String GET_JOB_EXECUTION = "SELECT ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION"
+ + " where ID = ?";
private JobInstance job;
@@ -390,6 +398,8 @@ public class SqlJobDao implements JobDao, InitializingBean {
jobExecution.setStartTime(rs.getTimestamp(2));
jobExecution.setEndTime(rs.getTimestamp(3));
jobExecution.setStatus(BatchStatus.getStatus(rs.getString(4)));
+ jobExecution.setExitStatus(new ExitStatus("Y".equals(rs
+ .getString(5)), rs.getString(6), rs.getString(7)));
return jobExecution;
}
diff --git a/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java b/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java
index 0ac56dda9..ff87f3ef0 100644
--- a/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java
+++ b/execution/src/main/java/org/springframework/batch/execution/repository/dao/SqlStepDao.java
@@ -28,6 +28,7 @@ import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.repository.NoSuchBatchDomainObjectException;
import org.springframework.batch.execution.repository.dao.SqlJobDao.JobExecutionRowMapper;
+import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.support.PropertiesConverter;
@@ -69,18 +70,18 @@ public class SqlStepDao implements StepDao, InitializingBean {
// StepExecution statements
private static final String SAVE_STEP_EXECUTION = "INSERT into %PREFIX%STEP_EXECUTION(ID, VERSION, STEP_ID, JOB_EXECUTION_ID, START_TIME, "
- + "END_TIME, STATUS, COMMIT_COUNT, TASK_COUNT, TASK_STATISTICS, EXIT_CODE, EXIT_MESSAGE) "
- + "values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+ + "END_TIME, STATUS, COMMIT_COUNT, TASK_COUNT, TASK_STATISTICS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE) "
+ + "values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String UPDATE_STEP_EXECUTION = "UPDATE %PREFIX%STEP_EXECUTION set START_TIME = ?, END_TIME = ?, "
- + "STATUS = ?, COMMIT_COUNT = ?, TASK_COUNT = ?, TASK_STATISTICS = ?, EXIT_CODE = ?, "
+ + "STATUS = ?, COMMIT_COUNT = ?, TASK_COUNT = ?, TASK_STATISTICS = ?, CONTINUABLE = ? , EXIT_CODE = ?, "
+ "EXIT_MESSAGE = ? where ID = ?";
private static final String GET_STEP_EXECUTION_COUNT = "SELECT count(ID) from %PREFIX%STEP_EXECUTION where "
+ "STEP_ID = ?";
private static final String FIND_STEP_EXECUTIONS = "SELECT ID, JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, COMMIT_COUNT,"
- + " TASK_COUNT, TASK_STATISTICS, EXIT_CODE, EXIT_MESSAGE from %PREFIX%STEP_EXECUTION where STEP_ID = ?";
+ + " TASK_COUNT, TASK_STATISTICS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%STEP_EXECUTION where STEP_ID = ?";
private JdbcOperations jdbcTemplate;
@@ -108,7 +109,8 @@ public class SqlStepDao implements StepDao, InitializingBean {
* Injection setter for job dao. Used to save {@link JobExecution}
* instances.
*
- * @param jobDao a {@link JobDao}
+ * @param jobDao
+ * a {@link JobDao}
*/
public void setJobDao(JobDao jobDao) {
this.jobDao = jobDao;
@@ -270,8 +272,10 @@ public class SqlStepDao implements StepDao, InitializingBean {
stepExecution.getCommitCount(),
stepExecution.getTaskCount(),
PropertiesConverter.propertiesToString(stepExecution
- .getStatistics()), stepExecution.getExitCode(),
- stepExecution.getExitDescription() };
+ .getStatistics()),
+ stepExecution.getExitStatus().isContinuable() ? "Y" : "N",
+ stepExecution.getExitStatus().getExitCode(),
+ stepExecution.getExitStatus().getExitDescription() };
jdbcTemplate.update(getQuery(SAVE_STEP_EXECUTION), parameters);
}
@@ -309,8 +313,11 @@ public class SqlStepDao implements StepDao, InitializingBean {
stepExecution.getCommitCount(),
stepExecution.getTaskCount(),
PropertiesConverter.propertiesToString(stepExecution
- .getStatistics()), stepExecution.getExitCode(),
- stepExecution.getExitDescription(), stepExecution.getId() };
+ .getStatistics()),
+ stepExecution.getExitStatus().isContinuable() ? "Y" : "N",
+ stepExecution.getExitStatus().getExitCode(),
+ stepExecution.getExitStatus().getExitDescription(),
+ stepExecution.getId() };
jdbcTemplate.update(getQuery(UPDATE_STEP_EXECUTION), parameters);
}
@@ -355,8 +362,8 @@ public class SqlStepDao implements StepDao, InitializingBean {
stepExecution.setTaskCount(rs.getInt(7));
stepExecution.setStatistics(PropertiesConverter
.stringToProperties(rs.getString(8)));
- stepExecution.setExitCode(rs.getString(9));
- stepExecution.setExitDescription(rs.getString(10));
+ stepExecution.setExitStatus(new ExitStatus("Y".equals(rs
+ .getString(9)), rs.getString(10), rs.getString(11)));
return stepExecution;
}
};
diff --git a/execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java b/execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java
index c35110475..86d97913e 100644
--- a/execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java
+++ b/execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java
@@ -266,8 +266,7 @@ public class SimpleStepExecutor implements StepExecutor {
}
finally {
- stepExecution.setExitCode(status.getExitCode());
- stepExecution.setExitDescription(status.getExitDescription());
+ stepExecution.setExitStatus(status);
stepExecution.setEndTime(new Timestamp(System.currentTimeMillis()));
try {
jobRepository.saveOrUpdate(stepExecution);
diff --git a/execution/src/main/resources/org/springframework/batch/execution/repository/dao/JobExecution.hbm.xml b/execution/src/main/resources/org/springframework/batch/execution/repository/dao/JobExecution.hbm.xml
index 90b066021..33133314b 100644
--- a/execution/src/main/resources/org/springframework/batch/execution/repository/dao/JobExecution.hbm.xml
+++ b/execution/src/main/resources/org/springframework/batch/execution/repository/dao/JobExecution.hbm.xml
@@ -16,7 +16,11 @@
-
+
+
+
+
+
diff --git a/execution/src/main/resources/org/springframework/batch/execution/repository/dao/StepExecution.hbm.xml b/execution/src/main/resources/org/springframework/batch/execution/repository/dao/StepExecution.hbm.xml
index 8c6ee24b4..67e836399 100644
--- a/execution/src/main/resources/org/springframework/batch/execution/repository/dao/StepExecution.hbm.xml
+++ b/execution/src/main/resources/org/springframework/batch/execution/repository/dao/StepExecution.hbm.xml
@@ -20,7 +20,11 @@
-
+
+
+
+
+
diff --git a/execution/src/main/resources/schema-db2.sql b/execution/src/main/resources/schema-db2.sql
deleted file mode 100644
index 32d0e22ed..000000000
--- a/execution/src/main/resources/schema-db2.sql
+++ /dev/null
@@ -1,56 +0,0 @@
--- Autogenerated: do not edit this file
-DROP TABLE BATCH_STEP_EXECUTION ;
-DROP TABLE BATCH_JOB_EXECUTION ;
-DROP TABLE BATCH_STEP ;
-DROP TABLE BATCH_JOB ;
-
-DROP SEQUENCE BATCH_STEP_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_STEP_SEQ ;
-DROP SEQUENCE BATCH_JOB_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_JOB_SEQ ;
-
--- Autogenerated: do not edit this file
-CREATE TABLE BATCH_JOB (
- ID BIGINT PRIMARY KEY NOT NULL,
- VERSION BIGINT,
- JOB_NAME VARCHAR(100) NOT NULL ,
- JOB_STREAM VARCHAR(20) ,
- SCHEDULE_DATE DATE ,
- JOB_RUN CHAR(2),
- STATUS VARCHAR(10) );
-
-CREATE TABLE BATCH_JOB_EXECUTION (
- ID BIGINT PRIMARY KEY NOT NULL,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- EXIT_CODE VARCHAR(250));
-
-CREATE TABLE BATCH_STEP (
- ID BIGINT PRIMARY KEY NOT NULL,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- STEP_NAME VARCHAR(100) NOT NULL,
- STATUS VARCHAR(10),
- RESTART_DATA VARCHAR(200));
-
-CREATE TABLE BATCH_STEP_EXECUTION (
- ID BIGINT PRIMARY KEY NOT NULL,
- VERSION BIGINT NOT NULL,
- STEP_ID BIGINT NOT NULL,
- JOB_EXECUTION_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- COMMIT_COUNT BIGINT ,
- TASK_COUNT BIGINT ,
- TASK_STATISTICS VARCHAR(250),
- EXIT_CODE VARCHAR(250),
- EXIT_MESSAGE VARCHAR(250));
-
-CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_STEP_SEQ;
-CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_JOB_SEQ;
diff --git a/execution/src/main/resources/schema-derby.sql b/execution/src/main/resources/schema-derby.sql
deleted file mode 100644
index bf2f8d700..000000000
--- a/execution/src/main/resources/schema-derby.sql
+++ /dev/null
@@ -1,56 +0,0 @@
--- Autogenerated: do not edit this file
-DROP TABLE BATCH_STEP_EXECUTION ;
-DROP TABLE BATCH_JOB_EXECUTION ;
-DROP TABLE BATCH_STEP ;
-DROP TABLE BATCH_JOB ;
-
-DROP SEQUENCE BATCH_STEP_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_STEP_SEQ ;
-DROP SEQUENCE BATCH_JOB_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_JOB_SEQ ;
-
--- Autogenerated: do not edit this file
-CREATE TABLE BATCH_JOB (
- ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
- VERSION BIGINT,
- JOB_NAME VARCHAR(100) NOT NULL ,
- JOB_STREAM VARCHAR(20) ,
- SCHEDULE_DATE DATE ,
- JOB_RUN CHAR(2),
- STATUS VARCHAR(10) );
-
-CREATE TABLE BATCH_JOB_EXECUTION (
- ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- EXIT_CODE VARCHAR(250));
-
-CREATE TABLE BATCH_STEP (
- ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- STEP_NAME VARCHAR(100) NOT NULL,
- STATUS VARCHAR(10),
- RESTART_DATA VARCHAR(200));
-
-CREATE TABLE BATCH_STEP_EXECUTION (
- ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
- VERSION BIGINT NOT NULL,
- STEP_ID BIGINT NOT NULL,
- JOB_EXECUTION_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- COMMIT_COUNT BIGINT ,
- TASK_COUNT BIGINT ,
- TASK_STATISTICS VARCHAR(250),
- EXIT_CODE VARCHAR(250),
- EXIT_MESSAGE VARCHAR(250));
-
-CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_STEP_SEQ;
-CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_JOB_SEQ;
diff --git a/execution/src/main/resources/schema-hsqldb.sql b/execution/src/main/resources/schema-hsqldb.sql
deleted file mode 100644
index 297529fdb..000000000
--- a/execution/src/main/resources/schema-hsqldb.sql
+++ /dev/null
@@ -1,64 +0,0 @@
--- Autogenerated: do not edit this file
-DROP TABLE BATCH_STEP_EXECUTION IF EXISTS;
-DROP TABLE BATCH_JOB_EXECUTION IF EXISTS;
-DROP TABLE BATCH_STEP IF EXISTS;
-DROP TABLE BATCH_JOB IF EXISTS;
-
-DROP TABLE BATCH_STEP_EXECUTION_SEQ IF EXISTS;
-DROP TABLE BATCH_STEP_SEQ IF EXISTS;
-DROP TABLE BATCH_JOB_EXECUTION_SEQ IF EXISTS;
-DROP TABLE BATCH_JOB_SEQ IF EXISTS;
-
--- Autogenerated: do not edit this file
-CREATE TABLE BATCH_JOB (
- ID BIGINT IDENTITY PRIMARY KEY ,
- VERSION BIGINT,
- JOB_NAME VARCHAR(100) NOT NULL ,
- JOB_STREAM VARCHAR(20) ,
- SCHEDULE_DATE DATE ,
- JOB_RUN CHAR(2),
- STATUS VARCHAR(10) );
-
-CREATE TABLE BATCH_JOB_EXECUTION (
- ID BIGINT IDENTITY PRIMARY KEY ,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- EXIT_CODE VARCHAR(250));
-
-CREATE TABLE BATCH_STEP (
- ID BIGINT IDENTITY PRIMARY KEY ,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- STEP_NAME VARCHAR(100) NOT NULL,
- STATUS VARCHAR(10),
- RESTART_DATA VARCHAR(200));
-
-CREATE TABLE BATCH_STEP_EXECUTION (
- ID BIGINT IDENTITY PRIMARY KEY ,
- VERSION BIGINT NOT NULL,
- STEP_ID BIGINT NOT NULL,
- JOB_EXECUTION_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- COMMIT_COUNT BIGINT ,
- TASK_COUNT BIGINT ,
- TASK_STATISTICS VARCHAR(250),
- EXIT_CODE VARCHAR(250),
- EXIT_MESSAGE VARCHAR(250));
-
-CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
- ID BIGINT IDENTITY
-);
-CREATE TABLE BATCH_STEP_SEQ (
- ID BIGINT IDENTITY
-);
-CREATE TABLE BATCH_JOB_EXECUTION_SEQ (
- ID BIGINT IDENTITY
-);
-CREATE TABLE BATCH_JOB_SEQ (
- ID BIGINT IDENTITY
-);
diff --git a/execution/src/main/resources/schema-oracle10g.sql b/execution/src/main/resources/schema-oracle10g.sql
deleted file mode 100644
index 038a1d6c2..000000000
--- a/execution/src/main/resources/schema-oracle10g.sql
+++ /dev/null
@@ -1,56 +0,0 @@
--- Autogenerated: do not edit this file
-DROP TABLE BATCH_STEP_EXECUTION ;
-DROP TABLE BATCH_JOB_EXECUTION ;
-DROP TABLE BATCH_STEP ;
-DROP TABLE BATCH_JOB ;
-
-DROP SEQUENCE BATCH_STEP_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_STEP_SEQ ;
-DROP SEQUENCE BATCH_JOB_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_JOB_SEQ ;
-
--- Autogenerated: do not edit this file
-CREATE TABLE BATCH_JOB (
- ID INT PRIMARY KEY ,
- VERSION INT,
- JOB_NAME VARCHAR(100) NOT NULL ,
- JOB_STREAM VARCHAR(20) ,
- SCHEDULE_DATE DATE ,
- JOB_RUN CHAR(2),
- STATUS VARCHAR(10) );
-
-CREATE TABLE BATCH_JOB_EXECUTION (
- ID INT PRIMARY KEY ,
- VERSION INT,
- JOB_ID INT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- EXIT_CODE VARCHAR(250));
-
-CREATE TABLE BATCH_STEP (
- ID INT PRIMARY KEY ,
- VERSION INT,
- JOB_ID INT NOT NULL,
- STEP_NAME VARCHAR(100) NOT NULL,
- STATUS VARCHAR(10),
- RESTART_DATA VARCHAR(200));
-
-CREATE TABLE BATCH_STEP_EXECUTION (
- ID INT PRIMARY KEY ,
- VERSION INT NOT NULL,
- STEP_ID INT NOT NULL,
- JOB_EXECUTION_ID INT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- COMMIT_COUNT INT ,
- TASK_COUNT INT ,
- TASK_STATISTICS VARCHAR(250),
- EXIT_CODE VARCHAR(250),
- EXIT_MESSAGE VARCHAR(250));
-
-CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_STEP_SEQ;
-CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_JOB_SEQ;
diff --git a/execution/src/main/resources/schema-postgresql.sql b/execution/src/main/resources/schema-postgresql.sql
deleted file mode 100644
index 638ab009c..000000000
--- a/execution/src/main/resources/schema-postgresql.sql
+++ /dev/null
@@ -1,56 +0,0 @@
--- Autogenerated: do not edit this file
-DROP TABLE BATCH_STEP_EXECUTION ;
-DROP TABLE BATCH_JOB_EXECUTION ;
-DROP TABLE BATCH_STEP ;
-DROP TABLE BATCH_JOB ;
-
-DROP SEQUENCE BATCH_STEP_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_STEP_SEQ ;
-DROP SEQUENCE BATCH_JOB_EXECUTION_SEQ ;
-DROP SEQUENCE BATCH_JOB_SEQ ;
-
--- Autogenerated: do not edit this file
-CREATE TABLE BATCH_JOB (
- ID BIGINT PRIMARY KEY ,
- VERSION BIGINT,
- JOB_NAME VARCHAR(100) NOT NULL ,
- JOB_STREAM VARCHAR(20) ,
- SCHEDULE_DATE DATE ,
- JOB_RUN CHAR(2),
- STATUS VARCHAR(10) );
-
-CREATE TABLE BATCH_JOB_EXECUTION (
- ID BIGINT PRIMARY KEY ,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- EXIT_CODE VARCHAR(250));
-
-CREATE TABLE BATCH_STEP (
- ID BIGINT PRIMARY KEY ,
- VERSION BIGINT,
- JOB_ID BIGINT NOT NULL,
- STEP_NAME VARCHAR(100) NOT NULL,
- STATUS VARCHAR(10),
- RESTART_DATA VARCHAR(200));
-
-CREATE TABLE BATCH_STEP_EXECUTION (
- ID BIGINT PRIMARY KEY ,
- VERSION BIGINT NOT NULL,
- STEP_ID BIGINT NOT NULL,
- JOB_EXECUTION_ID BIGINT NOT NULL,
- START_TIME TIMESTAMP NOT NULL ,
- END_TIME TIMESTAMP ,
- STATUS VARCHAR(10),
- COMMIT_COUNT BIGINT ,
- TASK_COUNT BIGINT ,
- TASK_STATISTICS VARCHAR(250),
- EXIT_CODE VARCHAR(250),
- EXIT_MESSAGE VARCHAR(250));
-
-CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_STEP_SEQ;
-CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ;
-CREATE SEQUENCE BATCH_JOB_SEQ;
diff --git a/execution/src/main/sql/init.sql.vpp b/execution/src/main/sql/init.sql.vpp
index b2c29a1ec..31e5ce40f 100644
--- a/execution/src/main/sql/init.sql.vpp
+++ b/execution/src/main/sql/init.sql.vpp
@@ -15,7 +15,9 @@ CREATE TABLE BATCH_JOB_EXECUTION (
START_TIME TIMESTAMP NOT NULL ,
END_TIME TIMESTAMP ,
STATUS VARCHAR(10),
- EXIT_CODE VARCHAR(250));
+ CONTINUABLE CHAR(1),
+ EXIT_CODE VARCHAR(20),
+ EXIT_MESSAGE VARCHAR(250));
CREATE TABLE BATCH_STEP (
ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED},
@@ -36,7 +38,8 @@ CREATE TABLE BATCH_STEP_EXECUTION (
COMMIT_COUNT ${BIGINT} ,
TASK_COUNT ${BIGINT} ,
TASK_STATISTICS VARCHAR(250),
- EXIT_CODE VARCHAR(250),
+ CONTINUABLE CHAR(1),
+ EXIT_CODE VARCHAR(20),
EXIT_MESSAGE VARCHAR(250));
#sequence( "BATCH_STEP_EXECUTION_SEQ" )
diff --git a/execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java b/execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java
index 171e765a0..7766df935 100644
--- a/execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java
+++ b/execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java
@@ -174,7 +174,7 @@ public class DefaultJobExecutorTests extends TestCase {
});
jobExecutor.run(jobConfiguration, jobExecution);
assertEquals(2, list.size());
- checkRepository(BatchStatus.COMPLETED, ExitStatus.FINISHED.getExitCode());
+ checkRepository(BatchStatus.COMPLETED, ExitStatus.FINISHED);
}
@@ -221,7 +221,7 @@ public class DefaultJobExecutorTests extends TestCase {
assertEquals(exception, e.getCause());
}
assertEquals(0, list.size());
- checkRepository(BatchStatus.STOPPED, ExitCodeExceptionClassifier.STEP_INTERRUPTED);
+ checkRepository(BatchStatus.STOPPED, new ExitStatus(false, ExitCodeExceptionClassifier.STEP_INTERRUPTED));
}
public void testFailed() throws Exception {
@@ -241,7 +241,7 @@ public class DefaultJobExecutorTests extends TestCase {
assertEquals(exception, e);
}
assertEquals(0, list.size());
- checkRepository(BatchStatus.FAILED, ExitCodeExceptionClassifier.FATAL_EXCEPTION);
+ checkRepository(BatchStatus.FAILED, new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION));
}
public void testStepShouldNotStart() throws Exception {
@@ -260,15 +260,15 @@ public class DefaultJobExecutorTests extends TestCase {
/*
* Check JobRepository to ensure status is being saved.
*/
- private void checkRepository(BatchStatus status, String exitCode) {
+ private void checkRepository(BatchStatus status, ExitStatus exitStatus) {
assertEquals(job, jobDao.findJobs(jobIdentifer).get(0));
// because map dao stores in memory, it can be checked directly
assertEquals(status, job.getStatus());
JobExecution jobExecution = (JobExecution) jobDao.findJobExecutions(job).get(0);
assertEquals(job.getId(), jobExecution.getJobId());
assertEquals(status, jobExecution.getStatus());
- if(exitCode != null){
- assertEquals(jobExecution.getExitCode(), exitCode);
+ if(exitStatus != null){
+ assertEquals(jobExecution.getExitStatus().getExitCode(), exitStatus.getExitCode());
}
}
diff --git a/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java b/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java
index eb88ae2d0..22fc9b54e 100644
--- a/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java
+++ b/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java
@@ -29,18 +29,20 @@ import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.repository.NoSuchBatchDomainObjectException;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
+import org.springframework.batch.repeat.ExitStatus;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
import org.springframework.util.ClassUtils;
/**
* @author Dave Syer
- *
+ *
*/
public abstract class AbstractJobDaoTests extends
AbstractTransactionalDataSourceSpringContextTests {
- private static final String GET_JOB_EXECUTION = "SELECT JOB_ID, START_TIME, END_TIME, STATUS, EXIT_CODE from "
+ private static final String GET_JOB_EXECUTION = "SELECT JOB_ID, START_TIME, END_TIME, STATUS, "
+ + "CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from "
+ "BATCH_JOB_EXECUTION where ID = ?";
protected JobDao jobDao;
@@ -164,18 +166,18 @@ public abstract class AbstractJobDaoTests extends
public void testUpdateJobExecution() {
jobExecution.setStatus(BatchStatus.COMPLETED);
- jobExecution.setExitCode("COMPLETED");
+ jobExecution.setExitStatus(ExitStatus.FINISHED);
jobExecution.setEndTime(new Timestamp(System.currentTimeMillis()));
jobDao.update(jobExecution);
List executions = retrieveJobExecution(jobExecution.getId());
assertEquals(executions.size(), 1);
validateJobExecution(jobExecution, (JobExecution) executions.get(0));
-
+
}
-
- public void testSaveJobExecution(){
-
+
+ public void testSaveJobExecution() {
+
List executions = retrieveJobExecution(jobExecution.getId());
assertEquals(executions.size(), 1);
validateJobExecution(jobExecution, (JobExecution) executions.get(0));
@@ -240,15 +242,15 @@ public abstract class AbstractJobDaoTests extends
assertEquals(job.getName(), ((Map) jobs.get(0)).get("JOB_NAME"));
}
-
- private void validateJobExecution(JobExecution lhs, JobExecution rhs){
-
- //equals operator only checks id
+
+ private void validateJobExecution(JobExecution lhs, JobExecution rhs) {
+
+ // equals operator only checks id
assertEquals(lhs, rhs);
assertEquals(lhs.getStartTime(), rhs.getStartTime());
assertEquals(lhs.getEndTime(), rhs.getEndTime());
assertEquals(lhs.getStatus(), rhs.getStatus());
- assertEquals(lhs.getExitCode(), rhs.getExitCode());
+ assertEquals(lhs.getExitStatus(), rhs.getExitStatus());
}
private List retrieveJobExecution(final Long id) {
@@ -256,12 +258,14 @@ public abstract class AbstractJobDaoTests extends
RowMapper rowMapper = new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
- JobExecution execution = new JobExecution(new JobInstance(jobRuntimeInformation, new Long(rs
- .getLong(1))));
+ JobExecution execution = new JobExecution(new JobInstance(
+ jobRuntimeInformation, new Long(rs.getLong(1))));
execution.setStartTime(rs.getTimestamp(2));
execution.setEndTime(rs.getTimestamp(3));
execution.setStatus(BatchStatus.getStatus(rs.getString(4)));
- execution.setExitCode(rs.getString(5));
+ // TODO: Add boolean for continuable to queries
+ execution.setExitStatus(new ExitStatus("Y".equals(rs
+ .getString(5)), rs.getString(6), rs.getString(7)));
execution.setId(id);
return execution;
diff --git a/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java b/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java
index e14082ffa..7d3b8d3ff 100644
--- a/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java
+++ b/execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java
@@ -28,6 +28,7 @@ import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.core.executor.ExitCodeExceptionClassifier;
import org.springframework.batch.core.runtime.JobIdentifier;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
+import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
@@ -165,16 +166,14 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
statistics.setProperty("statistic.key1", "0");
statistics.setProperty("statistic.key2", "5");
execution.setStatistics(statistics);
- execution.setExitCode(ExitCodeExceptionClassifier.FATAL_EXCEPTION);
- execution.setExitDescription("java.lang.Exception");
+ execution.setExitStatus(new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION, "java.lang.Exception"));
stepDao.save(execution);
List executions = stepDao.findStepExecutions(step2);
assertEquals(1, executions.size());
StepExecution tempExecution = (StepExecution)executions.get(0);
assertEquals(execution, tempExecution);
assertEquals(execution.getStatistics(), tempExecution.getStatistics());
- assertEquals(tempExecution.getExitCode(), execution.getExitCode());
- assertEquals(tempExecution.getExitDescription(), execution.getExitDescription());
+ assertEquals(execution.getExitStatus(), tempExecution.getExitStatus());
}
public void testUpdateStepExecution(){
@@ -184,15 +183,13 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
stepExecution.setCommitCount(5);
stepExecution.setTaskCount(5);
stepExecution.setStatistics(new Properties());
- stepExecution.setExitCode(ExitCodeExceptionClassifier.FATAL_EXCEPTION);
- stepExecution.setExitDescription("java.lang.Exception");
+ stepExecution.setExitStatus(new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION, "java.lang.Exception"));
stepDao.update(stepExecution);
List executions = stepDao.findStepExecutions(step1);
assertEquals(1, executions.size());
StepExecution tempExecution = (StepExecution)executions.get(0);
assertEquals(stepExecution, tempExecution);
- assertEquals(tempExecution.getExitCode(), stepExecution.getExitCode());
- assertEquals(tempExecution.getExitDescription(), stepExecution.getExitDescription());
+ assertEquals(stepExecution.getExitStatus(), tempExecution.getExitStatus());
}
public void testUpdateStepExecutionWithNullId(){
diff --git a/execution/src/test/java/org/springframework/batch/execution/repository/dao/ExitStatusUserTypeTests.java b/execution/src/test/java/org/springframework/batch/execution/repository/dao/ExitStatusUserTypeTests.java
new file mode 100644
index 000000000..d675a78c1
--- /dev/null
+++ b/execution/src/test/java/org/springframework/batch/execution/repository/dao/ExitStatusUserTypeTests.java
@@ -0,0 +1,51 @@
+package org.springframework.batch.execution.repository.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Types;
+
+import junit.framework.TestCase;
+
+import org.easymock.MockControl;
+import org.springframework.batch.repeat.ExitStatus;
+
+public class ExitStatusUserTypeTests extends TestCase {
+
+ ExitStatusUserType type = new ExitStatusUserType();
+
+ public void testReturnedClass() {
+ assertEquals(ExitStatus.class, type.returnedClass());
+ }
+
+ public void testSqlTypes() {
+ int[] types = type.sqlTypes();
+ assertEquals(3, types.length);
+ assertEquals(Types.CHAR, types[0]);
+ }
+
+ public void testNullSafeGet() throws Exception {
+ String[] names = new String[] {"a", "b", "c"};
+ MockControl control = MockControl.createControl(ResultSet.class);
+ ResultSet rs = (ResultSet) control.getMock();
+ control.expectAndReturn(rs.getString(names[0]), "Y");
+ control.expectAndReturn(rs.getString(names[1]), "foo");
+ control.expectAndReturn(rs.getString(names[2]), "bar");
+ control.replay();
+ Object result = type.nullSafeGet(rs, names, null);
+ assertNotNull(result);
+ assertTrue(result instanceof ExitStatus);
+ control.verify();
+ }
+
+ public void testNullSafeSet() throws Exception {
+ MockControl control = MockControl.createControl(PreparedStatement.class);
+ PreparedStatement st = (PreparedStatement) control.getMock();
+ st.setString(2, "Y");
+ st.setString(3, ExitStatus.CONTINUABLE.getExitCode());
+ st.setString(4, ExitStatus.CONTINUABLE.getExitDescription());
+ control.replay();
+ type.nullSafeSet(st, ExitStatus.CONTINUABLE, 2);
+ control.verify();
+ }
+
+}
diff --git a/execution/src/test/java/org/springframework/batch/execution/repository/dao/ImmutableValueUserTypeTests.java b/execution/src/test/java/org/springframework/batch/execution/repository/dao/ImmutableValueUserTypeTests.java
new file mode 100644
index 000000000..e84701ff9
--- /dev/null
+++ b/execution/src/test/java/org/springframework/batch/execution/repository/dao/ImmutableValueUserTypeTests.java
@@ -0,0 +1,61 @@
+package org.springframework.batch.execution.repository.dao;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+
+import junit.framework.TestCase;
+
+public class ImmutableValueUserTypeTests extends TestCase {
+
+ ImmutableValueUserType type = new ImmutableValueUserType() {
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
+ throws HibernateException, SQLException {
+ return null;
+ }
+ public void nullSafeSet(PreparedStatement st, Object value, int index)
+ throws HibernateException, SQLException {
+ }
+ public Class returnedClass() {
+ return null;
+ }
+ public int[] sqlTypes() {
+ return null;
+ }
+ };
+
+ public void testAssemble() {
+ assertEquals("foo", type.assemble("foo", null));
+ }
+
+ public void testDeepCopy() {
+ assertEquals("foo", type.deepCopy("foo"));
+ }
+
+ public void testDisassemble() {
+ assertEquals("foo", type.disassemble("foo"));
+ }
+
+ public void testEqualsWithEqualObjects() {
+ assertTrue(type.equals("foo", "foo"));
+ }
+
+ public void testEqualsWithUnEqualObjects() {
+ assertFalse(type.equals("foo", "bar"));
+ }
+
+ public void testHashCodeObject() {
+ assertEquals("foo".hashCode(), type.hashCode("foo"));
+ }
+
+ public void testIsMutable() {
+ assertFalse(type.isMutable());
+ }
+
+ public void testReplace() {
+ assertEquals("foo",type.replace("foo", "bar", null));
+ }
+
+}
diff --git a/execution/src/test/java/org/springframework/batch/execution/step/simple/DefaultStepExecutorTests.java b/execution/src/test/java/org/springframework/batch/execution/step/simple/DefaultStepExecutorTests.java
index 127ad6083..c6a561e72 100644
--- a/execution/src/test/java/org/springframework/batch/execution/step/simple/DefaultStepExecutorTests.java
+++ b/execution/src/test/java/org/springframework/batch/execution/step/simple/DefaultStepExecutorTests.java
@@ -71,7 +71,9 @@ public class DefaultStepExecutorTests extends TestCase {
return module;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
@@ -79,7 +81,8 @@ public class DefaultStepExecutorTests extends TestCase {
stepExecutor = new DefaultStepExecutor();
stepExecutor.setRepository(new JobRepositorySupport());
stepConfiguration = new SimpleStepConfiguration();
- stepConfiguration.setTasklet(getTasklet(new String[] {"foo", "bar", "spam"}));
+ stepConfiguration.setTasklet(getTasklet(new String[] { "foo", "bar",
+ "spam" }));
// Only process one chunk:
RepeatTemplate template = new RepeatTemplate();
template.setCompletionPolicy(new SimpleCompletionPolicy(1));
@@ -94,8 +97,10 @@ public class DefaultStepExecutorTests extends TestCase {
StepInstance step = new StepInstance(new Long(9));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
+ JobExecution jobExecutionContext = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ StepExecution stepExecution = new StepExecution(step,
+ jobExecutionContext);
stepExecutor.process(stepConfiguration, stepExecution);
assertEquals(1, processed.size());
@@ -111,7 +116,8 @@ public class DefaultStepExecutorTests extends TestCase {
StepInstance step = new StepInstance(new Long(1));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, new Long(1)));
+ JobExecution jobExecution = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(1)));
step.setStepExecution(new StepExecution(step, jobExecution));
StepExecution stepExecution = new StepExecution(step, jobExecution);
@@ -130,16 +136,19 @@ public class DefaultStepExecutorTests extends TestCase {
final StepInstance step = new StepInstance(new Long(1));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- final JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- step.setStepExecution(new StepExecution(step,jobExecution));
- final StepExecution stepExecution = new StepExecution(step, jobExecution);
+ final JobExecution jobExecution = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ step.setStepExecution(new StepExecution(step, jobExecution));
+ final StepExecution stepExecution = new StepExecution(step,
+ jobExecution);
stepConfiguration.setTasklet(new Tasklet() {
public ExitStatus execute() throws Exception {
assertEquals(step, stepExecution.getStep());
assertEquals(1, jobExecution.getChunkContexts().size());
assertEquals(1, jobExecution.getStepContexts().size());
- assertNotNull(StepSynchronizationManager.getContext().getJobIdentifier());
+ assertNotNull(StepSynchronizationManager.getContext()
+ .getJobIdentifier());
processed.add("foo");
return ExitStatus.CONTINUABLE;
}
@@ -152,27 +161,30 @@ public class DefaultStepExecutorTests extends TestCase {
public void testRepository() throws Exception {
- SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapStepDao());
+ SimpleJobRepository repository = new SimpleJobRepository(
+ new MapJobDao(), new MapStepDao());
stepExecutor.setRepository(repository);
StepInstance step = new StepInstance(new Long(1));
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
+ JobExecution jobExecutionContext = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ StepExecution stepExecution = new StepExecution(step,
+ jobExecutionContext);
stepExecutor.process(stepConfiguration, stepExecution);
assertEquals(1, processed.size());
}
- public void testIncrementRollbackCount(){
+ public void testIncrementRollbackCount() {
- Tasklet tasklet = new Tasklet(){
+ Tasklet tasklet = new Tasklet() {
public ExitStatus execute() throws Exception {
int counter = 0;
counter++;
- if(counter == 1){
+ if (counter == 1) {
throw new Exception();
}
@@ -184,27 +196,29 @@ public class DefaultStepExecutorTests extends TestCase {
StepInstance step = new StepInstance(new Long(1));
stepConfiguration.setTasklet(tasklet);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
+ JobExecution jobExecutionContext = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ StepExecution stepExecution = new StepExecution(step,
+ jobExecutionContext);
- try{
+ try {
stepExecutor.process(stepConfiguration, stepExecution);
- }
- catch(Exception ex){
- assertEquals(step.getStepExecution().getRollbackCount(), new Integer(1));
+ } catch (Exception ex) {
+ assertEquals(step.getStepExecution().getRollbackCount(),
+ new Integer(1));
}
}
- public void testExitCodeDefaultClassification(){
+ public void testExitCodeDefaultClassification() {
- Tasklet tasklet = new Tasklet(){
+ Tasklet tasklet = new Tasklet() {
public ExitStatus execute() throws Exception {
int counter = 0;
counter++;
- if(counter == 1){
+ if (counter == 1) {
throw new RuntimeException();
}
@@ -216,35 +230,39 @@ public class DefaultStepExecutorTests extends TestCase {
StepInstance step = new StepInstance(new Long(1));
stepConfiguration.setTasklet(tasklet);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
+ JobExecution jobExecutionContext = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ StepExecution stepExecution = new StepExecution(step,
+ jobExecutionContext);
- try{
+ try {
stepExecutor.process(stepConfiguration, stepExecution);
- }
- catch(Exception ex){
- assertEquals(step.getStepExecution().getExitCode(), ExitCodeExceptionClassifier.FATAL_EXCEPTION);
- assertEquals(step.getStepExecution().getExitDescription(), "java.lang.RuntimeException");
+ } catch (Exception ex) {
+ assertEquals(step.getStepExecution().getExitStatus(),
+ new ExitStatus(false,
+ ExitCodeExceptionClassifier.FATAL_EXCEPTION,
+ "java.lang.RuntimeException"));
}
}
-
/*
* make sure a job that has never been executed before, but does have
* saveRestartData = true, doesn't have restoreFrom called on it.
*/
- public void testNonRestartedJob(){
+ public void testNonRestartedJob() {
StepInstance step = new StepInstance(new Long(1));
MockRestartableTasklet tasklet = new MockRestartableTasklet();
stepConfiguration.setTasklet(tasklet);
stepConfiguration.setSaveRestartData(true);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
+ JobExecution jobExecutionContext = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ StepExecution stepExecution = new StepExecution(step,
+ jobExecutionContext);
- try{
+ try {
stepExecutor.process(stepConfiguration, stepExecution);
- }catch(Throwable t){
+ } catch (Throwable t) {
fail();
}
@@ -253,22 +271,24 @@ public class DefaultStepExecutorTests extends TestCase {
}
/*
- * make sure a job that has been executed before, and is therefore being restarted,
- * is restored.
+ * make sure a job that has been executed before, and is therefore being
+ * restarted, is restored.
*/
- public void testRestartedJob(){
+ public void testRestartedJob() {
StepInstance step = new StepInstance(new Long(1));
step.setStepExecutionCount(1);
MockRestartableTasklet tasklet = new MockRestartableTasklet();
stepConfiguration.setTasklet(tasklet);
stepConfiguration.setSaveRestartData(true);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
+ JobExecution jobExecutionContext = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ StepExecution stepExecution = new StepExecution(step,
+ jobExecutionContext);
- try{
+ try {
stepExecutor.process(stepConfiguration, stepExecution);
- }catch(Throwable t){
+ } catch (Throwable t) {
fail();
}
@@ -277,22 +297,24 @@ public class DefaultStepExecutorTests extends TestCase {
}
/*
- * Test that a job that is being restarted, but has saveRestartData
- * set to false, doesn't have restore or getRestartData called on it.
+ * Test that a job that is being restarted, but has saveRestartData set to
+ * false, doesn't have restore or getRestartData called on it.
*/
- public void testNoSaveRestartDataRestartableJob(){
+ public void testNoSaveRestartDataRestartableJob() {
StepInstance step = new StepInstance(new Long(1));
step.setStepExecutionCount(1);
MockRestartableTasklet tasklet = new MockRestartableTasklet();
stepConfiguration.setTasklet(tasklet);
stepConfiguration.setSaveRestartData(false);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecutionContext = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
+ JobExecution jobExecutionContext = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
+ StepExecution stepExecution = new StepExecution(step,
+ jobExecutionContext);
- try{
+ try {
stepExecutor.process(stepConfiguration, stepExecution);
- }catch(Throwable t){
+ } catch (Throwable t) {
fail();
}
@@ -301,30 +323,31 @@ public class DefaultStepExecutorTests extends TestCase {
}
/*
- * Even though the job is restarted, and saveRestartData is true,
- * nothing will be restored because the Tasklet does not implement
- * Restartable.
+ * Even though the job is restarted, and saveRestartData is true, nothing
+ * will be restored because the Tasklet does not implement Restartable.
*/
- public void testRestartJobOnNonRestartableTasklet(){
+ public void testRestartJobOnNonRestartableTasklet() {
StepInstance step = new StepInstance(new Long(1));
step.setStepExecutionCount(1);
- stepConfiguration.setTasklet(new Tasklet(){
+ stepConfiguration.setTasklet(new Tasklet() {
public ExitStatus execute() throws Exception {
- return ExitStatus.FINISHED;
- }});
+ return ExitStatus.FINISHED;
+ }
+ });
stepConfiguration.setSaveRestartData(true);
SimpleJobIdentifier jobIdentifier = new SimpleJobIdentifier("FOO");
- JobExecution jobExecution = new JobExecution(new JobInstance(jobIdentifier, new Long(3)));
+ JobExecution jobExecution = new JobExecution(new JobInstance(
+ jobIdentifier, new Long(3)));
StepExecution stepExecution = new StepExecution(step, jobExecution);
- try{
+ try {
stepExecutor.process(stepConfiguration, stepExecution);
- }catch(Throwable t){
+ } catch (Throwable t) {
fail();
}
}
- private class MockRestartableTasklet implements Tasklet, Restartable{
+ private class MockRestartableTasklet implements Tasklet, Restartable {
private boolean getRestartDataCalled = false;
private boolean restoreFromCalled = false;
@@ -352,49 +375,42 @@ public class DefaultStepExecutorTests extends TestCase {
}
/*
- * StepExecutor will never pass StepInterruptedException to the exceptionClassifier.
- * This may or may not stay the same, so the test will remain commented out
- * for reference purposes.
+ * StepExecutor will never pass StepInterruptedException to the
+ * exceptionClassifier. This may or may not stay the same, so the test will
+ * remain commented out for reference purposes.
+ */
+ /*
+ * public void testExitCodeInterruptedClassification(){
+ *
+ * StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy(){
+ *
+ * public void checkInterrupted(RepeatContext context) throws
+ * StepInterruptedException { throw new StepInterruptedException(""); }
+ * };
+ *
+ * stepExecutor.setInterruptionPolicy(interruptionPolicy);
+ *
+ * Tasklet tasklet = new Tasklet(){
+ *
+ * public ExitStatus execute() throws Exception { int counter = 0;
+ * counter++;
+ *
+ * if(counter == 1){ throw new StepInterruptedException(""); }
+ *
+ * return ExitStatus.CONTINUABLE; }
+ * };
+ *
+ * StepInstance step = new StepInstance(new Long(1));
+ * stepConfiguration.setTasklet(tasklet); JobExecutionContext
+ * jobExecutionContext = new JobExecutionContext(new
+ * SimpleJobIdentifier("FOO"), new JobInstance(new Long(3))); StepExecution
+ * stepExecution = new StepExecution(step, jobExecutionContext);
+ *
+ * try{ stepExecutor.process(stepConfiguration, stepExecution); }
+ * catch(Exception ex){
+ * assertEquals(ExitCodeExceptionClassifier.STEP_INTERRUPTED,
+ * step.getStepExecution().getExitCode() );
+ * assertEquals(step.getStepExecution().getExitDescription(),
+ * "java.lang.RuntimeException"); } }
*/
-/* public void testExitCodeInterruptedClassification(){
-
- StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy(){
-
- public void checkInterrupted(RepeatContext context)
- throws StepInterruptedException {
- throw new StepInterruptedException("");
- }
-
- };
-
- stepExecutor.setInterruptionPolicy(interruptionPolicy);
-
- Tasklet tasklet = new Tasklet(){
-
- public ExitStatus execute() throws Exception {
- int counter = 0;
- counter++;
-
- if(counter == 1){
- throw new StepInterruptedException("");
- }
-
- return ExitStatus.CONTINUABLE;
- }
-
- };
-
- StepInstance step = new StepInstance(new Long(1));
- stepConfiguration.setTasklet(tasklet);
- JobExecutionContext jobExecutionContext = new JobExecutionContext(new SimpleJobIdentifier("FOO"), new JobInstance(new Long(3)));
- StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
-
- try{
- stepExecutor.process(stepConfiguration, stepExecution);
- }
- catch(Exception ex){
- assertEquals(ExitCodeExceptionClassifier.STEP_INTERRUPTED, step.getStepExecution().getExitCode() );
- assertEquals(step.getStepExecution().getExitDescription(), "java.lang.RuntimeException");
- }
- }*/
}
diff --git a/execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql b/execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql
index eb3630793..90d3debc4 100644
--- a/execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql
+++ b/execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql
@@ -15,7 +15,9 @@ CREATE TABLE BATCH_JOB_EXECUTION (
START_TIME TIMESTAMP NOT NULL ,
END_TIME TIMESTAMP ,
STATUS VARCHAR(10),
- EXIT_CODE VARCHAR(250));
+ CONTINUABLE CHAR(1),
+ EXIT_CODE VARCHAR(20),
+ EXIT_MESSAGE VARCHAR(250));
CREATE TABLE BATCH_STEP (
ID BIGINT IDENTITY PRIMARY KEY ,
@@ -36,7 +38,8 @@ CREATE TABLE BATCH_STEP_EXECUTION (
COMMIT_COUNT BIGINT ,
TASK_COUNT BIGINT ,
TASK_STATISTICS VARCHAR(250),
- EXIT_CODE VARCHAR(250),
+ CONTINUABLE CHAR(1),
+ EXIT_CODE VARCHAR(20),
EXIT_MESSAGE VARCHAR(250));
CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
diff --git a/infrastructure/src/main/java/org/springframework/batch/repeat/ExitStatus.java b/infrastructure/src/main/java/org/springframework/batch/repeat/ExitStatus.java
index 94e805066..c30f89511 100644
--- a/infrastructure/src/main/java/org/springframework/batch/repeat/ExitStatus.java
+++ b/infrastructure/src/main/java/org/springframework/batch/repeat/ExitStatus.java
@@ -32,20 +32,25 @@ public class ExitStatus implements Serializable {
*/
public static final ExitStatus RUNNING = new ExitStatus(true, "RUNNING");
+ /**
+ * Convenient constant value representing unknown state - assumed continuable.
+ */
+ public static final ExitStatus UNKNOWN = new ExitStatus(true, "UNKNOWN");
+
/**
* Convenient constant value representing unfinished processing.
*/
- public static ExitStatus CONTINUABLE = new ExitStatus(true);
+ public static final ExitStatus CONTINUABLE = new ExitStatus(true, "CONTINUABLE");
/**
* Convenient constant value representing finished processing.
*/
- public static ExitStatus FINISHED = new ExitStatus(false, "COMPLETED");
+ public static final ExitStatus FINISHED = new ExitStatus(false, "COMPLETED");
/**
* Convenient constant value representing finished processing with an error.
*/
- public static ExitStatus FAILED = new ExitStatus(false, "FAILED");
+ public static final ExitStatus FAILED = new ExitStatus(false, "FAILED");
private final boolean continuable;
@@ -121,6 +126,18 @@ public class ExitStatus implements Serializable {
return "continuable=" + continuable + ";exitCode=" + exitCode
+ ";exitDescription=" + exitDescription;
}
+
+ /**
+ * Compare the fields one by one.
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj==null) {
+ return false;
+ }
+ return toString().equals(obj.toString());
+ }
/**
* Add an exit code to an existing {@link ExitStatus}.
diff --git a/infrastructure/src/test/java/org/springframework/batch/repeat/ExitStatusTests.java b/infrastructure/src/test/java/org/springframework/batch/repeat/ExitStatusTests.java
index c527fba6f..d2819db50 100644
--- a/infrastructure/src/test/java/org/springframework/batch/repeat/ExitStatusTests.java
+++ b/infrastructure/src/test/java/org/springframework/batch/repeat/ExitStatusTests.java
@@ -40,7 +40,7 @@ public class ExitStatusTests extends TestCase {
public void testExitStatusConstantsContinuable() {
ExitStatus status = ExitStatus.CONTINUABLE;
assertTrue(status.isContinuable());
- assertEquals("", status.getExitCode());
+ assertEquals("CONTINUABLE", status.getExitCode());
}
/**
@@ -51,6 +51,24 @@ public class ExitStatusTests extends TestCase {
assertFalse(status.isContinuable());
assertEquals("COMPLETED", status.getExitCode());
}
+
+ /**
+ * Test equality of exit statuses.
+ *
+ * @throws Exception
+ */
+ public void testEqualsWithSameProperties() throws Exception {
+ assertEquals(ExitStatus.CONTINUABLE, new ExitStatus(true, "CONTINUABLE"));
+ }
+
+ /**
+ * Test equality of exit statuses.
+ *
+ * @throws Exception
+ */
+ public void testEqualsWithNull() throws Exception {
+ assertFalse(ExitStatus.CONTINUABLE.equals(null));
+ }
/**
* Test method for {@link org.springframework.batch.repeat.ExitStatus#and(boolean)}.