1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.batch.admin.service;
17
18 import static org.springframework.batch.support.DatabaseType.SYBASE;
19
20 import java.sql.Types;
21
22 import javax.sql.DataSource;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import org.springframework.batch.core.configuration.JobLocator;
28 import org.springframework.batch.core.configuration.ListableJobLocator;
29 import org.springframework.batch.core.explore.JobExplorer;
30 import org.springframework.batch.core.jsr.JsrJobParametersConverter;
31 import org.springframework.batch.core.jsr.launch.JsrJobOperator;
32 import org.springframework.batch.core.launch.JobLauncher;
33 import org.springframework.batch.core.repository.ExecutionContextSerializer;
34 import org.springframework.batch.core.repository.JobRepository;
35 import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao;
36 import org.springframework.batch.core.repository.dao.ExecutionContextDao;
37 import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao;
38 import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao;
39 import org.springframework.batch.core.repository.dao.JdbcStepExecutionDao;
40 import org.springframework.batch.core.repository.dao.XStreamExecutionContextStringSerializer;
41 import org.springframework.batch.item.database.support.DataFieldMaxValueIncrementerFactory;
42 import org.springframework.batch.item.database.support.DefaultDataFieldMaxValueIncrementerFactory;
43 import org.springframework.batch.support.DatabaseType;
44 import org.springframework.beans.factory.FactoryBean;
45 import org.springframework.beans.factory.InitializingBean;
46 import org.springframework.jdbc.core.JdbcOperations;
47 import org.springframework.jdbc.core.JdbcTemplate;
48 import org.springframework.jdbc.support.lob.DefaultLobHandler;
49 import org.springframework.jdbc.support.lob.LobHandler;
50 import org.springframework.transaction.PlatformTransactionManager;
51 import org.springframework.util.Assert;
52 import org.springframework.util.StringUtils;
53
54
55
56
57
58
59
60
61 public class SimpleJobServiceFactoryBean implements FactoryBean<JobService>, InitializingBean {
62 private static final Log logger = LogFactory.getLog(SimpleJobServiceFactoryBean.class);
63
64 private DataSource dataSource;
65
66 private JdbcOperations jdbcTemplate;
67
68 private String databaseType;
69
70 private String tablePrefix = AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX;
71
72 private DataFieldMaxValueIncrementerFactory incrementerFactory;
73
74 private int maxVarCharLength = AbstractJdbcBatchMetadataDao.DEFAULT_EXIT_MESSAGE_LENGTH;
75
76 private LobHandler lobHandler;
77
78 private JobRepository jobRepository;
79
80 private JobLauncher jobLauncher;
81
82 private ListableJobLocator jobLocator;
83
84 private JobExplorer jobExplorer;
85
86 private ExecutionContextSerializer serializer;
87
88 private PlatformTransactionManager transactionManager;
89
90 public void setTransactionManager(PlatformTransactionManager transactionManager) {
91 this.transactionManager = transactionManager;
92 }
93
94
95
96
97
98
99
100
101
102
103 public void setLobHandler(LobHandler lobHandler) {
104 this.lobHandler = lobHandler;
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119 public void setMaxVarCharLength(int maxVarCharLength) {
120 this.maxVarCharLength = maxVarCharLength;
121 }
122
123
124
125
126
127 public void setDataSource(DataSource dataSource) {
128 this.dataSource = dataSource;
129 }
130
131
132
133
134
135
136 public void setDatabaseType(String dbType) {
137 this.databaseType = dbType;
138 }
139
140
141
142
143
144 public void setTablePrefix(String tablePrefix) {
145 this.tablePrefix = tablePrefix;
146 }
147
148
149
150
151
152
153 public void setIncrementerFactory(DataFieldMaxValueIncrementerFactory incrementerFactory) {
154 this.incrementerFactory = incrementerFactory;
155 }
156
157 public void setJobExplorer(JobExplorer jobExplorer) {
158 this.jobExplorer = jobExplorer;
159 }
160
161
162
163
164
165
166 public void setJobRepository(JobRepository jobRepository) {
167 this.jobRepository = jobRepository;
168 }
169
170
171
172
173
174 public void setJobLauncher(JobLauncher jobLauncher) {
175 this.jobLauncher = jobLauncher;
176 }
177
178
179
180
181
182 public void setJobLocator(ListableJobLocator jobLocator) {
183 this.jobLocator = jobLocator;
184 }
185
186
187
188
189
190
191
192
193
194
195 public void setSerializer(ExecutionContextSerializer serializer) {
196 this.serializer = serializer;
197 }
198
199 public void afterPropertiesSet() throws Exception {
200
201 Assert.notNull(dataSource, "DataSource must not be null.");
202 Assert.notNull(jobRepository, "JobRepository must not be null.");
203 Assert.notNull(jobLocator, "JobLocator must not be null.");
204 Assert.notNull(jobLauncher, "JobLauncher must not be null.");
205 Assert.notNull(jobExplorer, "JobExplorer must not be null.");
206
207 jdbcTemplate = new JdbcTemplate(dataSource);
208
209 if (incrementerFactory == null) {
210 incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource);
211 }
212
213 if (databaseType == null) {
214 databaseType = DatabaseType.fromMetaData(dataSource).name();
215 logger.info("No database type set, using meta data indicating: " + databaseType);
216 }
217
218 if (lobHandler == null) {
219 lobHandler = new DefaultLobHandler();
220 }
221
222 if (serializer == null) {
223 XStreamExecutionContextStringSerializer defaultSerializer = new XStreamExecutionContextStringSerializer();
224 defaultSerializer.afterPropertiesSet();
225
226 serializer = defaultSerializer;
227 }
228
229 Assert.isTrue(incrementerFactory.isSupportedIncrementerType(databaseType), "'" + databaseType
230 + "' is an unsupported database type. The supported database types are "
231 + StringUtils.arrayToCommaDelimitedString(incrementerFactory.getSupportedIncrementerTypes()));
232
233 }
234
235 protected SearchableJobInstanceDao createJobInstanceDao() throws Exception {
236 JdbcSearchableJobInstanceDao dao = new JdbcSearchableJobInstanceDao();
237 dao.setJdbcTemplate(jdbcTemplate);
238 dao.setJobIncrementer(incrementerFactory.getIncrementer(databaseType, tablePrefix + "JOB_SEQ"));
239 dao.setTablePrefix(tablePrefix);
240 dao.afterPropertiesSet();
241 return dao;
242 }
243
244 protected SearchableJobExecutionDao createJobExecutionDao() throws Exception {
245 JdbcSearchableJobExecutionDao dao = new JdbcSearchableJobExecutionDao();
246 dao.setDataSource(dataSource);
247 dao.setJobExecutionIncrementer(incrementerFactory.getIncrementer(databaseType, tablePrefix
248 + "JOB_EXECUTION_SEQ"));
249 dao.setTablePrefix(tablePrefix);
250 dao.setClobTypeToUse(determineClobTypeToUse(this.databaseType));
251 dao.setExitMessageLength(maxVarCharLength);
252 dao.afterPropertiesSet();
253 return dao;
254 }
255
256 protected SearchableStepExecutionDao createStepExecutionDao() throws Exception {
257 JdbcSearchableStepExecutionDao dao = new JdbcSearchableStepExecutionDao();
258 dao.setDataSource(dataSource);
259 dao.setStepExecutionIncrementer(incrementerFactory.getIncrementer(databaseType, tablePrefix
260 + "STEP_EXECUTION_SEQ"));
261 dao.setTablePrefix(tablePrefix);
262 dao.setClobTypeToUse(determineClobTypeToUse(this.databaseType));
263 dao.setExitMessageLength(maxVarCharLength);
264 dao.afterPropertiesSet();
265 return dao;
266 }
267
268 protected ExecutionContextDao createExecutionContextDao() throws Exception {
269 JdbcExecutionContextDao dao = new JdbcExecutionContextDao();
270 dao.setJdbcTemplate(jdbcTemplate);
271 dao.setTablePrefix(tablePrefix);
272 dao.setClobTypeToUse(determineClobTypeToUse(this.databaseType));
273 if (lobHandler != null) {
274 dao.setLobHandler(lobHandler);
275 }
276 dao.setSerializer(serializer);
277 dao.afterPropertiesSet();
278
279 dao.setShortContextLength(maxVarCharLength);
280 return dao;
281 }
282
283 private int determineClobTypeToUse(String databaseType) {
284 if (SYBASE == DatabaseType.valueOf(databaseType.toUpperCase())) {
285 return Types.LONGVARCHAR;
286 }
287 else {
288 return Types.CLOB;
289 }
290 }
291
292
293
294
295
296
297 public JobService getObject() throws Exception {
298 JsrJobParametersConverter jobParametersConverter = new JsrJobParametersConverter(dataSource);
299 jobParametersConverter.afterPropertiesSet();
300 JsrJobOperator jsrJobOperator = new JsrJobOperator(jobExplorer, jobRepository, jobParametersConverter, transactionManager);
301 jsrJobOperator.afterPropertiesSet();
302 return new SimpleJobService(createJobInstanceDao(), createJobExecutionDao(), createStepExecutionDao(),
303 jobRepository, jobLauncher, jobLocator, createExecutionContextDao(), jsrJobOperator);
304 }
305
306
307
308
309
310
311
312
313 public Class<? extends JobService> getObjectType() {
314 return SimpleJobService.class;
315 }
316
317
318
319
320
321
322
323 public boolean isSingleton() {
324 return true;
325 }
326
327 }