Skip to content

Commit 7ecac1c

Browse files
committed
Add default converters for java.util.Date parameter type
Resolves #4297 Resolves #4270
1 parent 8aaf1d3 commit 7ecac1c

File tree

13 files changed

+294
-40
lines changed

13 files changed

+294
-40
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/configuration/support/DefaultBatchConfiguration.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
import org.springframework.batch.core.configuration.BatchConfigurationException;
2828
import org.springframework.batch.core.configuration.JobRegistry;
29+
import org.springframework.batch.core.converter.DateToStringConverter;
30+
import org.springframework.batch.core.converter.StringToDateConverter;
2931
import org.springframework.batch.core.explore.JobExplorer;
3032
import org.springframework.batch.core.explore.support.JobExplorerFactoryBean;
3133
import org.springframework.batch.core.launch.JobLauncher;
@@ -375,7 +377,10 @@ protected TaskExecutor getTaskExecutor() {
375377
* @return the {@link ConfigurableConversionService} to use.
376378
*/
377379
protected ConfigurableConversionService getConversionService() {
378-
return new DefaultConversionService();
380+
DefaultConversionService conversionService = new DefaultConversionService();
381+
conversionService.addConverter(new DateToStringConverter());
382+
conversionService.addConverter(new StringToDateConverter());
383+
return conversionService;
379384
}
380385

381386
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.core.converter;
17+
18+
import java.time.format.DateTimeFormatter;
19+
20+
/**
21+
* Base class for {@link java.util.Date} converters.
22+
*
23+
* @author Mahmoud Ben Hassine
24+
* @since 5.0.1
25+
*/
26+
public class AbstractDateConverter {
27+
28+
protected DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_INSTANT;
29+
30+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.core.converter;
17+
18+
import java.util.Date;
19+
20+
import org.springframework.core.convert.converter.Converter;
21+
22+
/**
23+
* {@link Converter} implementation from {@link java.util.Date} to {@link String}.
24+
*
25+
* This converter formats dates according to the
26+
* {@link java.time.format.DateTimeFormatter#ISO_INSTANT} format.
27+
*
28+
* @author Mahmoud Ben Hassine
29+
* @since 5.0.1
30+
*/
31+
public class DateToStringConverter extends AbstractDateConverter implements Converter<Date, String> {
32+
33+
@Override
34+
public String convert(Date source) {
35+
return super.dateTimeFormatter.format(source.toInstant());
36+
}
37+
38+
}

spring-batch-core/src/main/java/org/springframework/batch/core/converter/DefaultJobParametersConverter.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2022 the original author or authors.
2+
* Copyright 2006-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,14 +53,29 @@
5353
* service should be configured with a converter to and from string literals to job
5454
* parameter types.
5555
*
56+
* By default, the Spring conversion service is augmented to support the conversion of the
57+
* following types:
58+
*
59+
* <ul>
60+
* <li>{@link java.util.Date}: in the
61+
* {@link java.time.format.DateTimeFormatter#ISO_INSTANT} format</li>
62+
* </ul>
63+
*
5664
* @author Dave Syer
5765
* @author Michael Minella
5866
* @author Mahmoud Ben Hassine
5967
*
6068
*/
6169
public class DefaultJobParametersConverter implements JobParametersConverter {
6270

63-
protected ConfigurableConversionService conversionService = new DefaultConversionService();
71+
protected ConfigurableConversionService conversionService;
72+
73+
public DefaultJobParametersConverter() {
74+
DefaultConversionService conversionService = new DefaultConversionService();
75+
conversionService.addConverter(new DateToStringConverter());
76+
conversionService.addConverter(new StringToDateConverter());
77+
this.conversionService = conversionService;
78+
}
6479

6580
/**
6681
* @see org.springframework.batch.core.converter.JobParametersConverter#getJobParameters(java.util.Properties)

spring-batch-core/src/main/java/org/springframework/batch/core/converter/JsonJobParametersConverter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@
4747
* service should be configured with a converter to and from string literals to job
4848
* parameter types.
4949
*
50+
* By default, the Spring conversion service is augmented to support the conversion of the
51+
* following types:
52+
*
53+
* <ul>
54+
* <li>{@link java.util.Date}: in the
55+
* {@link java.time.format.DateTimeFormatter#ISO_INSTANT} format</li>
56+
* </ul>
57+
*
5058
* @author Mahmoud Ben Hassine
5159
* @since 5.0
5260
*
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.core.converter;
17+
18+
import java.time.Instant;
19+
import java.util.Date;
20+
21+
import org.springframework.core.convert.converter.Converter;
22+
23+
/**
24+
* {@link Converter} implementation from {@link String} to {@link java.util.Date}.
25+
*
26+
* This converter expects strings in the
27+
* {@link java.time.format.DateTimeFormatter#ISO_INSTANT} format.
28+
*
29+
* @author Mahmoud Ben Hassine
30+
* @since 5.0.1
31+
*/
32+
public class StringToDateConverter extends AbstractDateConverter implements Converter<String, Date> {
33+
34+
@Override
35+
public Date convert(String source) {
36+
return Date.from(super.dateTimeFormatter.parse(source, Instant::from));
37+
}
38+
39+
}

spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,7 +21,8 @@
2121

2222
import javax.sql.DataSource;
2323

24-
import org.springframework.batch.core.explore.JobExplorer;
24+
import org.springframework.batch.core.converter.DateToStringConverter;
25+
import org.springframework.batch.core.converter.StringToDateConverter;
2526
import org.springframework.batch.core.repository.ExecutionContextSerializer;
2627
import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao;
2728
import org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer;
@@ -164,7 +165,10 @@ public void afterPropertiesSet() throws Exception {
164165
}
165166

166167
if (this.conversionService == null) {
167-
this.conversionService = new DefaultConversionService();
168+
DefaultConversionService conversionService = new DefaultConversionService();
169+
conversionService.addConverter(new DateToStringConverter());
170+
conversionService.addConverter(new StringToDateConverter());
171+
this.conversionService = conversionService;
168172
}
169173

170174
super.afterPropertiesSet();

spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2022 the original author or authors.
2+
* Copyright 2006-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@
2020
import java.sql.SQLException;
2121
import java.sql.Timestamp;
2222
import java.sql.Types;
23-
import java.time.LocalDateTime;
2423
import java.util.HashMap;
2524
import java.util.HashSet;
2625
import java.util.List;
@@ -37,6 +36,8 @@
3736
import org.springframework.batch.core.JobInstance;
3837
import org.springframework.batch.core.JobParameter;
3938
import org.springframework.batch.core.JobParameters;
39+
import org.springframework.batch.core.converter.DateToStringConverter;
40+
import org.springframework.batch.core.converter.StringToDateConverter;
4041
import org.springframework.beans.factory.InitializingBean;
4142
import org.springframework.core.convert.support.ConfigurableConversionService;
4243
import org.springframework.core.convert.support.DefaultConversionService;
@@ -106,7 +107,14 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements
106107

107108
private DataFieldMaxValueIncrementer jobExecutionIncrementer;
108109

109-
private ConfigurableConversionService conversionService = new DefaultConversionService();
110+
private ConfigurableConversionService conversionService;
111+
112+
public JdbcJobExecutionDao() {
113+
DefaultConversionService conversionService = new DefaultConversionService();
114+
conversionService.addConverter(new DateToStringConverter());
115+
conversionService.addConverter(new StringToDateConverter());
116+
this.conversionService = conversionService;
117+
}
110118

111119
/**
112120
* Public setter for the exit message length in database. Do not set this if you
@@ -127,7 +135,7 @@ public void setJobExecutionIncrementer(DataFieldMaxValueIncrementer jobExecution
127135
}
128136

129137
/**
130-
* Set the conversion service to use to convert job parameters from String literal to
138+
* Set the conversion service to use to convert job parameters from String literals to
131139
* typed values and vice versa.
132140
*/
133141
public void setConversionService(@NonNull ConfigurableConversionService conversionService) {

spring-batch-core/src/main/java/org/springframework/batch/core/repository/support/JobRepositoryFactoryBean.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,11 +20,14 @@
2020
import java.nio.charset.Charset;
2121
import java.nio.charset.StandardCharsets;
2222
import java.sql.Types;
23+
2324
import javax.sql.DataSource;
2425

2526
import org.apache.commons.logging.Log;
2627
import org.apache.commons.logging.LogFactory;
2728

29+
import org.springframework.batch.core.converter.DateToStringConverter;
30+
import org.springframework.batch.core.converter.StringToDateConverter;
2831
import org.springframework.batch.core.repository.ExecutionContextSerializer;
2932
import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao;
3033
import org.springframework.batch.core.repository.dao.DefaultExecutionContextSerializer;
@@ -235,7 +238,10 @@ public void afterPropertiesSet() throws Exception {
235238
}
236239

237240
if (this.conversionService == null) {
238-
this.conversionService = new DefaultConversionService();
241+
DefaultConversionService conversionService = new DefaultConversionService();
242+
conversionService.addConverter(new DateToStringConverter());
243+
conversionService.addConverter(new StringToDateConverter());
244+
this.conversionService = conversionService;
239245
}
240246

241247
super.afterPropertiesSet();
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.core.converter;
17+
18+
import java.time.Instant;
19+
import java.util.Date;
20+
21+
import org.junit.jupiter.api.Assertions;
22+
import org.junit.jupiter.api.Test;
23+
24+
/**
25+
* Test class for {@link DateToStringConverter}.
26+
*
27+
* @author Mahmoud Ben Hassine
28+
*/
29+
class DateToStringConverterTest {
30+
31+
private final DateToStringConverter converter = new DateToStringConverter();
32+
33+
@Test
34+
void testConvert() {
35+
// given
36+
Date date = Date.from(Instant.EPOCH);
37+
38+
// when
39+
String converted = this.converter.convert(date);
40+
41+
// then
42+
Assertions.assertEquals("1970-01-01T00:00:00Z", converted);
43+
}
44+
45+
}

0 commit comments

Comments
 (0)