Skip to content

Add support to use any type as a job parameter #4204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ public class DefaultJobKeyGenerator implements JobKeyGenerator<JobParameters> {
public String generateKey(JobParameters source) {

Assert.notNull(source, "source must not be null");
Map<String, JobParameter> props = source.getParameters();
Map<String, JobParameter<?>> props = source.getParameters();
StringBuilder stringBuffer = new StringBuilder();
List<String> keys = new ArrayList<>(props.keySet());
Collections.sort(keys);
for (String key : keys) {
JobParameter jobParameter = props.get(key);
JobParameter<?> jobParameter = props.get(key);
if (jobParameter.isIdentifying()) {
String value = jobParameter.getValue() == null ? "" : jobParameter.toString();
String value = jobParameter.toString();
stringBuffer.append(key).append("=").append(value).append(";");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@
package org.springframework.batch.core;

import java.io.Serializable;
import java.util.Date;

import org.springframework.lang.NonNull;
import org.springframework.util.Assert;

/**
* Domain representation of a parameter to a batch job. Only the following types can be
* parameters: String, Long, Date, and Double. The identifying flag is used to indicate if
* the parameter is to be used as part of the identification of a job instance.
* Domain representation of a parameter to a batch job. The identifying flag is used to
* indicate if the parameter is to be used as part of the identification of a job
* instance.
*
* @author Lucas Ward
* @author Dave Syer
Expand All @@ -34,87 +33,35 @@
* @since 2.0
*
*/
public class JobParameter implements Serializable {
public class JobParameter<T> implements Serializable {

private final Object parameter;
private T value;

private final ParameterType parameterType;
private Class<T> type;

private final boolean identifying;
private boolean identifying;

/**
* Construct a new {@code JobParameter} from a {@link String}.
* @param parameter {@link String} instance. Must not be {@code null}.
* @param identifying {@code true} if the {@code JobParameter} should be identifying.
* reate a new {@link JobParameter}.
* @param value the value of the parameter. Must not be {@code null}.
* @param type the type of the parameter. Must not be {@code null}.
* @param identifying true if the parameter is identifying. false otherwise.
*/
public JobParameter(@NonNull String parameter, boolean identifying) {
this(parameter, identifying, ParameterType.STRING);
}

/**
* Construct a new {@code JobParameter} from a {@link Long}.
* @param parameter {@link Long} instance. Must not be {@code null}.
* @param identifying {@code true} if the {@code JobParameter} should be identifying.
*/
public JobParameter(@NonNull Long parameter, boolean identifying) {
this(parameter, identifying, ParameterType.LONG);
}

/**
* Construct a new {@code JobParameter} from a {@link Date}.
* @param parameter {@link Date} instance. Must not be {@code null}.
* @param identifying {@code true} if the {@code JobParameter} should be identifying.
*/
public JobParameter(@NonNull Date parameter, boolean identifying) {
this(parameter, identifying, ParameterType.DATE);
}

/**
* Construct a new {@code JobParameter} from a {@link Double}.
* @param parameter {@link Double} instance. Must not be {@code null}.
* @param identifying {@code true} if the {@code JobParameter} should be identifying.
*/
public JobParameter(@NonNull Double parameter, boolean identifying) {
this(parameter, identifying, ParameterType.DOUBLE);
}

private JobParameter(Object parameter, boolean identifying, ParameterType parameterType) {
Assert.notNull(parameter, "parameter must not be null");
this.parameter = parameter;
this.parameterType = parameterType;
public JobParameter(@NonNull T value, @NonNull Class<T> type, boolean identifying) {
Assert.notNull(value, "value must not be null");
Assert.notNull(value, "type must not be null");
this.value = value;
this.type = type;
this.identifying = identifying;
}

/**
* Construct a new {@code JobParameter} from a {@link String}.
* @param parameter A {@link String} instance.
* Create a new identifying {@link JobParameter}.
* @param value the value of the parameter. Must not be {@code null}.
* @param type the type of the parameter. Must not be {@code null}.
*/
public JobParameter(String parameter) {
this(parameter, true);
}

/**
* Construct a new {@code JobParameter} from a {@link Long}.
* @param parameter A {@link Long} instance.
*/
public JobParameter(Long parameter) {
this(parameter, true);
}

/**
* Construct a new {@code JobParameter} as a {@link Date}.
* @param parameter A {@link Date} instance.
*/
public JobParameter(Date parameter) {
this(parameter, true);
}

/**
* Construct a new {@code JobParameter} from a {@link Double}.
* @param parameter A {@link Double} instance.
*/
public JobParameter(Double parameter) {
this(parameter, true);
public JobParameter(@NonNull T value, @NonNull Class<T> type) {
this(value, type, true);
}

/**
Expand All @@ -128,15 +75,16 @@ public boolean isIdentifying() {
/**
* @return the value contained within this {@code JobParameter}.
*/
public Object getValue() {
return parameter;
public T getValue() {
return value;
}

/**
* @return a {@link ParameterType} representing the type of this parameter.
* Return the type of the parameter.
* @return the type of the parameter
*/
public ParameterType getType() {
return parameterType;
public Class<T> getType() {
return type;
}

@Override
Expand All @@ -150,41 +98,17 @@ public boolean equals(Object obj) {
}

JobParameter rhs = (JobParameter) obj;
return parameterType == rhs.parameterType && parameter.equals(rhs.parameter);
return type == rhs.type && value.equals(rhs.value);
}

@Override
public String toString() {
return parameterType == ParameterType.DATE ? "" + ((Date) parameter).getTime() : parameter.toString();
return "{" + "value=" + value + ", type=" + type + ", identifying=" + identifying + '}';
}

@Override
public int hashCode() {
return 7 + 21 * parameter.hashCode();
}

/**
* Enumeration representing the type of {@link JobParameter}.
*/
public enum ParameterType {

/**
* String parameter type.
*/
STRING,
/**
* Date parameter type.
*/
DATE,
/**
* Long parameter type.
*/
LONG,
/**
* Double parameter type.
*/
DOUBLE;

return 7 + 21 * value.hashCode();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
package org.springframework.batch.core;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
* Value object representing runtime parameters to a batch job. Because the parameters
Expand All @@ -46,7 +49,7 @@
@SuppressWarnings("serial")
public class JobParameters implements Serializable {

private final Map<String, JobParameter> parameters;
private final Map<String, JobParameter<?>> parameters;

/**
* Default constructor.
Expand All @@ -61,7 +64,7 @@ public JobParameters() {
* @param parameters The {@link Map} that contains a {@code String} key and a
* {@link JobParameter} value.
*/
public JobParameters(Map<String, JobParameter> parameters) {
public JobParameters(Map<String, JobParameter<?>> parameters) {
this.parameters = new LinkedHashMap<>(parameters);
}

Expand All @@ -75,8 +78,11 @@ public Long getLong(String key) {
if (!parameters.containsKey(key)) {
return null;
}
Object value = parameters.get(key).getValue();
return value == null ? null : ((Long) value).longValue();
JobParameter<?> jobParameter = parameters.get(key);
if (!jobParameter.getType().equals(Long.class)) {
throw new IllegalArgumentException("Key " + key + " is not of type Long");
}
return (Long) jobParameter.getValue();
}

/**
Expand Down Expand Up @@ -104,8 +110,14 @@ public Long getLong(String key, @Nullable Long defaultValue) {
*/
@Nullable
public String getString(String key) {
JobParameter value = parameters.get(key);
return value == null ? null : value.toString();
if (!parameters.containsKey(key)) {
return null;
}
JobParameter<?> jobParameter = parameters.get(key);
if (!jobParameter.getType().equals(String.class)) {
throw new IllegalArgumentException("Key " + key + " is not of type String");
}
return (String) jobParameter.getValue();
}

/**
Expand Down Expand Up @@ -136,8 +148,11 @@ public Double getDouble(String key) {
if (!parameters.containsKey(key)) {
return null;
}
Double value = (Double) parameters.get(key).getValue();
return value == null ? null : value.doubleValue();
JobParameter<?> jobParameter = parameters.get(key);
if (!jobParameter.getType().equals(Double.class)) {
throw new IllegalArgumentException("Key " + key + " is not of type Double");
}
return (Double) jobParameter.getValue();
}

/**
Expand Down Expand Up @@ -165,7 +180,14 @@ public Double getDouble(String key, @Nullable Double defaultValue) {
*/
@Nullable
public Date getDate(String key) {
return this.getDate(key, null);
if (!parameters.containsKey(key)) {
return null;
}
JobParameter<?> jobParameter = parameters.get(key);
if (!jobParameter.getType().equals(Date.class)) {
throw new IllegalArgumentException("Key " + key + " is not of type java.util.Date");
}
return (Date) jobParameter.getValue();
}

/**
Expand All @@ -179,19 +201,24 @@ public Date getDate(String key) {
@Nullable
public Date getDate(String key, @Nullable Date defaultValue) {
if (parameters.containsKey(key)) {
return (Date) parameters.get(key).getValue();
return getDate(key);
}
else {
return defaultValue;
}
}

@Nullable
public JobParameter<?> getParameter(String key) {
Assert.notNull(key, "key must not be null");
return parameters.get(key);
}

/**
* Get a map of all parameters, including {@link String}, {@link Long}, and
* {@link Date} types.
* Get a map of all parameters.
* @return an unmodifiable map containing all parameters.
*/
public Map<String, JobParameter> getParameters() {
public Map<String, JobParameter<?>> getParameters() {
return Collections.unmodifiableMap(parameters);
}

Expand Down Expand Up @@ -223,17 +250,25 @@ public int hashCode() {

@Override
public String toString() {
return parameters.toString();
List<String> parameters = new ArrayList<>();
for (Map.Entry<String, JobParameter<?>> entry : this.parameters.entrySet()) {
parameters.add(String.format("'%s':'%s'", entry.getKey(), entry.getValue()));
}
return new StringBuilder("{").append(String.join(",", parameters)).append("}").toString();
}

/**
* @return The {@link Properties} that contain the key and values for the
* {@link JobParameter} objects.
* @deprecated since 5.0, scheduled for removal in 5.2. Use
* {@link org.springframework.batch.core.converter.JobParametersConverter#getProperties(JobParameters)}
*
*/
@Deprecated(since = "5.0", forRemoval = true)
public Properties toProperties() {
Properties props = new Properties();

for (Map.Entry<String, JobParameter> param : parameters.entrySet()) {
for (Map.Entry<String, JobParameter<?>> param : parameters.entrySet()) {
if (param.getValue() != null) {
props.put(param.getKey(), Objects.toString(param.getValue().toString(), ""));
}
Expand Down
Loading