BATCH-84: Modified JobIdentifier interface to include new JobRuntimeParameters value object, and modified its subclasses accordingly.
This commit is contained in:
@@ -1,30 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>spring-batch-core</name>
|
||||
<comment>Core domain for batch processing, expressing a domain of Jobs, Steps, Chunks, etc.</comment>
|
||||
<projects>
|
||||
<project>spring-batch-infrastructure</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.devzuz.q.maven.jdt.core.mavenIncrementalBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.devzuz.q.maven.jdt.core.mavenNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>spring-batch-core</name>
|
||||
<comment>Core domain for batch processing, expressing a domain of Jobs, Steps, Chunks, etc.</comment>
|
||||
<projects>
|
||||
<project>spring-batch-infrastructure</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.devzuz.q.maven.jdt.core.mavenIncrementalBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.devzuz.q.maven.jdt.core.mavenNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
|
||||
package org.springframework.batch.core.domain;
|
||||
|
||||
|
||||
/**
|
||||
* Identifier strategy for {@link JobInstance}. Different batch projects can
|
||||
* have different approaches and requirements regarding the identity of a job.
|
||||
* The minimum requirement is to provide a unique name to identify a job. Other
|
||||
* applications or projects might add other properties like a schedule date, or
|
||||
* an additional label (code).
|
||||
* The minimum requirement is to provide a unique name to identify a job and JobRuntimeParameters.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface JobIdentifier {
|
||||
|
||||
@@ -34,5 +34,13 @@ public interface JobIdentifier {
|
||||
* @return the name of the job
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* A simple getter for the {@link JobRuntimeParameters} that also identify
|
||||
* this job.
|
||||
*
|
||||
* @return JobRuntimeParameters
|
||||
*/
|
||||
public JobRuntimeParameters getRuntimeParameters();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.springframework.batch.core.domain;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Value object representing runtime parameters to a batch job. Because
|
||||
* the parameters have no individual meaning outside of the JobIdentifier they
|
||||
* are contained within, it is a value object rather than an entity. It is also
|
||||
* extremely important that a parameters object can be reliably compared to another
|
||||
* for equality, in order to determine if one JobIdentifier equals another.
|
||||
* Furthermore, because these parameters will need to be persisted, it is vital
|
||||
* that the types added are restricted.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @since 1.0
|
||||
*/
|
||||
public class JobRuntimeParameters {
|
||||
|
||||
private final Map stringMap;
|
||||
|
||||
private final Map longMap;
|
||||
|
||||
private final Map dateMap;
|
||||
|
||||
/**
|
||||
* Default constructor. Creates a new empty JobRuntimeParameters. It should be noted
|
||||
* that this constructor should only be used if an empty parameters is needed, since
|
||||
* JobRuntimeParameters is immutable.
|
||||
*/
|
||||
public JobRuntimeParameters(){
|
||||
this.stringMap = new HashMap();
|
||||
this.longMap = new HashMap();
|
||||
this.dateMap = new HashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new parameters object based upon three maps for each of the three
|
||||
* data types. See {@link JobRuntimeParametersBuilder} for an easier way to
|
||||
* create paramters.
|
||||
*
|
||||
* @param stringMap
|
||||
* @param longMap
|
||||
* @param dateMap
|
||||
*/
|
||||
public JobRuntimeParameters(Map stringMap, Map longMap, Map dateMap){
|
||||
super();
|
||||
|
||||
validateMap(stringMap, String.class);
|
||||
validateMap(longMap, Long.class);
|
||||
validateMap(dateMap, Date.class);
|
||||
this.stringMap = stringMap;
|
||||
this.longMap = longMap;
|
||||
this.dateMap = copyDateMap(dateMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Typesafe Getter for the String represented by the provided key.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public String getString(String key){
|
||||
return (String)stringMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Typesafe Getter for the Long represented by the provided key.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Long getLong(String key){
|
||||
return (Long)longMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Typesafe Getter for the Date represented by the provided key.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public Date getDate(String key){
|
||||
return (Date)dateMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of all parameters, including string, long, and date. It should be noted
|
||||
* that a Collections$UnmodifiableMap is returned, ensuring immutability.
|
||||
*
|
||||
* @return an unmodifiable map containing all parameters.
|
||||
*/
|
||||
public Map getParameters(){
|
||||
Map tempMap = new HashMap(stringMap);
|
||||
tempMap.putAll(longMap);
|
||||
tempMap.putAll(dateMap);
|
||||
return Collections.unmodifiableMap(tempMap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience method for validating that a the provided map only contains a particular
|
||||
* type as a value, with only a String as a key.
|
||||
*/
|
||||
private void validateMap(Map map, Class type){
|
||||
|
||||
for(Iterator it = map.entrySet().iterator();it.hasNext();){
|
||||
|
||||
Entry entry = (Entry)it.next();
|
||||
if(entry.getKey() instanceof String == false){
|
||||
throw new IllegalArgumentException("All parameter keys must be strings.");
|
||||
}
|
||||
if(entry.getValue().getClass() != type){
|
||||
throw new IllegalArgumentException("The values in this map must be of type:[" + type +
|
||||
"].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience method for copying Date values to ensure immutability.
|
||||
*/
|
||||
private Map copyDateMap(Map dateMap){
|
||||
Map tempMap = new HashMap();
|
||||
|
||||
for(Iterator it = dateMap.entrySet().iterator();it.hasNext();){
|
||||
Entry entry = (Entry)it.next();
|
||||
Date date = (Date)entry.getValue();
|
||||
tempMap.put(entry.getKey(), new Date(date.getTime()));
|
||||
}
|
||||
|
||||
return tempMap;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if(obj instanceof JobRuntimeParameters == false){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(this == obj){
|
||||
return true;
|
||||
}
|
||||
|
||||
JobRuntimeParameters parameters = (JobRuntimeParameters)obj;
|
||||
|
||||
//Since the type contained by each map is known, it's safe to call Map.equals()
|
||||
if(getParameters().equals(parameters.getParameters())){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
|
||||
return new HashCodeBuilder(7, 21).
|
||||
append(stringMap).
|
||||
append(longMap).
|
||||
append(dateMap).
|
||||
toHashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
||||
return stringMap.toString() + longMap.toString() + dateMap.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.springframework.batch.core.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Helper class for creating JobRuntimeParameters. Useful because of all JobRuntimeParameters
|
||||
* are immutable, and require 3 separate maps of the three supported types to ensure typesafety.
|
||||
* Once created, it can be used in the same was a java.lang.StringBuilder (except, order is irrelevant),
|
||||
* by adding various parameters types and creating a valid JobRuntimeParametres once finished.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @since 1.0
|
||||
* @see JobRuntimeParameters
|
||||
*/
|
||||
public class JobRuntimeParametersBuilder {
|
||||
|
||||
private final Map stringMap;
|
||||
|
||||
private final Map longMap;
|
||||
|
||||
private final Map dateMap;
|
||||
|
||||
/**
|
||||
* Default constructor. Initializes the builder
|
||||
*/
|
||||
public JobRuntimeParametersBuilder() {
|
||||
|
||||
this.stringMap = new HashMap();
|
||||
this.longMap = new HashMap();
|
||||
this.dateMap = new HashMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new String parameter for the given key.
|
||||
*
|
||||
* @param key - parameter accessor.
|
||||
* @param parameter - runtime parameter
|
||||
* @return a refernece to this object.
|
||||
*/
|
||||
public JobRuntimeParametersBuilder addString(String key, String parameter){
|
||||
Assert.notNull(parameter, "Parameter must not be null.");
|
||||
stringMap.put(key, parameter);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Date parameter for the given key.
|
||||
*
|
||||
* @param key - parameter accessor.
|
||||
* @param parameter - runtime parameter
|
||||
* @return a refernece to this object.
|
||||
*/
|
||||
public JobRuntimeParametersBuilder addDate(String key, Date parameter){
|
||||
Assert.notNull(parameter, "Parameter must not be null.");
|
||||
dateMap.put(key, new Date(parameter.getTime()));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Long parameter for the given key.
|
||||
*
|
||||
* @param key - parameter accessor.
|
||||
* @param parameter - runtime parameter
|
||||
* @return a refernece to this object.
|
||||
*/
|
||||
public JobRuntimeParametersBuilder addLong(String key, Long parameter){
|
||||
Assert.notNull(parameter, "Parameter must not be null.");
|
||||
longMap.put(key, parameter);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion method that takes the current state of this builder and returns it as
|
||||
* a JobruntimeParameters object.
|
||||
*
|
||||
* @return a valid JobRuntimeParameters object.
|
||||
*/
|
||||
public JobRuntimeParameters toJobRuntimeParameters(){
|
||||
return new JobRuntimeParameters(stringMap, longMap, dateMap);
|
||||
}
|
||||
}
|
||||
@@ -18,22 +18,27 @@ package org.springframework.batch.core.runtime;
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
import org.springframework.batch.core.domain.JobIdentifier;
|
||||
import org.springframework.batch.core.domain.JobRuntimeParameters;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Simple, immutable, implementation of the JobIdentifier interface.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class SimpleJobIdentifier implements JobIdentifier {
|
||||
|
||||
private String name;
|
||||
|
||||
private JobRuntimeParameters runtimeParameters;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* Default constructor. Since there it is required that the Identifier at least have a name,
|
||||
* the default constructor should not be called.
|
||||
*/
|
||||
public SimpleJobIdentifier() {
|
||||
private SimpleJobIdentifier() {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -42,8 +47,12 @@ public class SimpleJobIdentifier implements JobIdentifier {
|
||||
* @param name
|
||||
*/
|
||||
public SimpleJobIdentifier(String name) {
|
||||
super();
|
||||
this(name, new JobRuntimeParameters());
|
||||
}
|
||||
|
||||
public SimpleJobIdentifier(String name, JobRuntimeParameters runtimeParameters){
|
||||
this.name = name;
|
||||
this.runtimeParameters = runtimeParameters;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -53,24 +62,33 @@ public class SimpleJobIdentifier implements JobIdentifier {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the name.
|
||||
*
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public JobRuntimeParameters getRuntimeParameters() {
|
||||
return runtimeParameters;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ClassUtils.getShortName(getClass())+": name=" + name;
|
||||
return ClassUtils.getShortName(getClass())+": name=" + name + "parameters=" + runtimeParameters;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return EqualsBuilder.reflectionEquals(this, obj);
|
||||
|
||||
if(obj instanceof SimpleJobIdentifier == false){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(this == obj){
|
||||
return true;
|
||||
}
|
||||
|
||||
SimpleJobIdentifier rhs = (SimpleJobIdentifier)obj;
|
||||
return new EqualsBuilder().
|
||||
append(runtimeParameters,rhs.getRuntimeParameters()).
|
||||
append(name, rhs.getName()).
|
||||
isEquals();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return HashCodeBuilder.reflectionHashCode(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.springframework.batch.core.domain;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class JobRuntimeParametersBuilderTests extends TestCase {
|
||||
|
||||
JobRuntimeParametersBuilder parametersBuilder;
|
||||
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
parametersBuilder = new JobRuntimeParametersBuilder();
|
||||
parametersBuilder.addDate("SCHEDULE_DATE", date);
|
||||
parametersBuilder.addLong("LONG", new Long(1));
|
||||
parametersBuilder.addString("STRING", "string value");
|
||||
}
|
||||
|
||||
public void testToJobRuntimeParamters(){
|
||||
|
||||
JobRuntimeParameters parameters = parametersBuilder.toJobRuntimeParameters();
|
||||
assertEquals(parameters.getDate("SCHEDULE_DATE"), date);
|
||||
assertEquals(parameters.getLong("LONG"), new Long(1));
|
||||
assertEquals(parameters.getString("STRING"), "string value");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.springframework.batch.core.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public class JobRuntimeParametersTests extends TestCase {
|
||||
|
||||
JobRuntimeParameters parameters;
|
||||
|
||||
Map stringMap;
|
||||
|
||||
Map longMap;
|
||||
|
||||
Map dateMap;
|
||||
Date date1 = new Date(4321431242L);
|
||||
Date date2 = new Date(7809089900L);
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
parameters = getNewParameters();
|
||||
}
|
||||
|
||||
private JobRuntimeParameters getNewParameters(){
|
||||
|
||||
stringMap = new HashMap();
|
||||
stringMap.put("string.key1", "value1");
|
||||
stringMap.put("string.key2", "value2");
|
||||
|
||||
longMap = new HashMap();
|
||||
longMap.put("long.key1", new Long(1));
|
||||
longMap.put("long.key2", new Long(2));
|
||||
|
||||
dateMap = new HashMap();
|
||||
dateMap.put("date.key1", date1 );
|
||||
dateMap.put("date.key2", date2 );
|
||||
|
||||
return new JobRuntimeParameters(stringMap, longMap, dateMap);
|
||||
}
|
||||
|
||||
public void testBadLongConstructorException() throws Exception{
|
||||
|
||||
Map badLongMap = new HashMap();
|
||||
badLongMap.put("key", "bad long");
|
||||
|
||||
try{
|
||||
JobRuntimeParameters testParameters = new JobRuntimeParameters(stringMap, badLongMap, dateMap);
|
||||
fail();
|
||||
}
|
||||
catch(IllegalArgumentException ex){
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testBadStringConstructorException() throws Exception{
|
||||
|
||||
Map badMap = new HashMap();
|
||||
badMap.put("key", new Integer(2));
|
||||
|
||||
try{
|
||||
JobRuntimeParameters testParameters = new JobRuntimeParameters(badMap, longMap, dateMap);
|
||||
fail();
|
||||
}
|
||||
catch(IllegalArgumentException ex){
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testBadDateConstructorException() throws Exception{
|
||||
|
||||
Map badMap = new HashMap();
|
||||
badMap.put("key", new java.sql.Date(System.currentTimeMillis()));
|
||||
|
||||
try{
|
||||
JobRuntimeParameters testParameters = new JobRuntimeParameters(stringMap, longMap, badMap);
|
||||
fail();
|
||||
}
|
||||
catch(IllegalArgumentException ex){
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetString(){
|
||||
|
||||
assertEquals("value1", parameters.getString("string.key1"));
|
||||
assertEquals("value2", parameters.getString("string.key2"));
|
||||
}
|
||||
|
||||
public void testGetLong(){
|
||||
|
||||
assertEquals(new Long(1), parameters.getLong("long.key1"));
|
||||
assertEquals(new Long(2), parameters.getLong("long.key2"));
|
||||
}
|
||||
|
||||
public void testGetDate(){
|
||||
|
||||
assertEquals(date1, parameters.getDate("date.key1"));
|
||||
assertEquals(date2, parameters.getDate("date.key2"));
|
||||
}
|
||||
|
||||
public void testEquals(){
|
||||
|
||||
JobRuntimeParameters testParameters = getNewParameters();
|
||||
assertTrue(testParameters.equals(parameters));
|
||||
}
|
||||
|
||||
public void testToString(){
|
||||
|
||||
assertEquals("{string.key1=value1, string.key2=value2}{long.key1=1, long.key2=2}" +
|
||||
"{date.key2=Wed Apr 01 03:11:29 CST 1970, date.key1=Thu Feb 19 18:23:51 CST 1970}", parameters.toString());
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,6 @@ public class SimpleJobIdentifierTests extends TestCase {
|
||||
|
||||
private SimpleJobIdentifier identifier = new SimpleJobIdentifier("foo");
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.runtime.SimpleJobIdentifier#SimpleJobIdentifier()}.
|
||||
*/
|
||||
public void testSimpleJobIdentifier() {
|
||||
assertNull(new SimpleJobIdentifier().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
@@ -39,8 +32,6 @@ public class SimpleJobIdentifierTests extends TestCase {
|
||||
*/
|
||||
public void testGetName() {
|
||||
assertEquals("foo", identifier.getName());
|
||||
identifier.setName("bar");
|
||||
assertEquals("bar", identifier.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user