001/* 002 * Copyright 2002-2013 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.batch.core.explore.support; 018 019import javax.sql.DataSource; 020 021import org.springframework.batch.core.explore.JobExplorer; 022import org.springframework.batch.core.repository.ExecutionContextSerializer; 023import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao; 024import org.springframework.batch.core.repository.dao.ExecutionContextDao; 025import org.springframework.batch.core.repository.dao.Jackson2ExecutionContextStringSerializer; 026import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao; 027import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao; 028import org.springframework.batch.core.repository.dao.JdbcJobInstanceDao; 029import org.springframework.batch.core.repository.dao.JdbcStepExecutionDao; 030import org.springframework.batch.core.repository.dao.JobExecutionDao; 031import org.springframework.batch.core.repository.dao.JobInstanceDao; 032import org.springframework.batch.core.repository.dao.StepExecutionDao; 033import org.springframework.batch.core.repository.dao.XStreamExecutionContextStringSerializer; 034import org.springframework.batch.item.ExecutionContext; 035import org.springframework.beans.factory.FactoryBean; 036import org.springframework.beans.factory.InitializingBean; 037import org.springframework.jdbc.core.JdbcOperations; 038import org.springframework.jdbc.core.JdbcTemplate; 039import org.springframework.jdbc.support.incrementer.AbstractDataFieldMaxValueIncrementer; 040import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; 041import org.springframework.jdbc.support.lob.LobHandler; 042import org.springframework.util.Assert; 043 044/** 045 * A {@link FactoryBean} that automates the creation of a 046 * {@link SimpleJobExplorer} using JDBC DAO implementations. Requires the user 047 * to describe what kind of database they are using. 048 * 049 * @author Dave Syer 050 * @since 2.0 051 */ 052public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean 053implements InitializingBean { 054 055 private DataSource dataSource; 056 057 private JdbcOperations jdbcOperations; 058 059 private String tablePrefix = AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX; 060 061 private DataFieldMaxValueIncrementer incrementer = new AbstractDataFieldMaxValueIncrementer() { 062 @Override 063 protected long getNextKey() { 064 throw new IllegalStateException("JobExplorer is read only."); 065 } 066 }; 067 068 private LobHandler lobHandler; 069 070 private ExecutionContextSerializer serializer; 071 072 /** 073 * A custom implementation of the {@link ExecutionContextSerializer}. 074 * The default, if not injected, is the {@link XStreamExecutionContextStringSerializer}. 075 * 076 * @param serializer used to serialize/deserialize an {@link org.springframework.batch.item.ExecutionContext} 077 * @see ExecutionContextSerializer 078 */ 079 public void setSerializer(ExecutionContextSerializer serializer) { 080 this.serializer = serializer; 081 } 082 083 /** 084 * Public setter for the {@link DataSource}. 085 * 086 * @param dataSource 087 * a {@link DataSource} 088 */ 089 public void setDataSource(DataSource dataSource) { 090 this.dataSource = dataSource; 091 } 092 093 /** 094 * Public setter for the {@link JdbcOperations}. If this property is not set explicitly, 095 * a new {@link JdbcTemplate} will be created for the configured DataSource by default. 096 * @param jdbcOperations a {@link JdbcOperations} 097 */ 098 public void setJdbcOperations(JdbcOperations jdbcOperations) { 099 this.jdbcOperations = jdbcOperations; 100 } 101 102 /** 103 * Sets the table prefix for all the batch meta-data tables. 104 * 105 * @param tablePrefix prefix for the batch meta-data tables 106 */ 107 public void setTablePrefix(String tablePrefix) { 108 this.tablePrefix = tablePrefix; 109 } 110 111 /** 112 * The lob handler to use when saving {@link ExecutionContext} instances. 113 * Defaults to null which works for most databases. 114 * 115 * @param lobHandler Large object handler for saving {@link org.springframework.batch.item.ExecutionContext} 116 */ 117 public void setLobHandler(LobHandler lobHandler) { 118 this.lobHandler = lobHandler; 119 } 120 121 @Override 122 public void afterPropertiesSet() throws Exception { 123 124 Assert.notNull(dataSource, "DataSource must not be null."); 125 126 if (jdbcOperations == null) { 127 jdbcOperations = new JdbcTemplate(dataSource); 128 } 129 130 if(serializer == null) { 131 serializer = new Jackson2ExecutionContextStringSerializer(); 132 } 133 } 134 135 private JobExplorer getTarget() throws Exception { 136 return new SimpleJobExplorer(createJobInstanceDao(), 137 createJobExecutionDao(), createStepExecutionDao(), 138 createExecutionContextDao()); 139 } 140 141 @Override 142 protected ExecutionContextDao createExecutionContextDao() throws Exception { 143 JdbcExecutionContextDao dao = new JdbcExecutionContextDao(); 144 dao.setJdbcTemplate(jdbcOperations); 145 dao.setLobHandler(lobHandler); 146 dao.setTablePrefix(tablePrefix); 147 dao.setSerializer(serializer); 148 dao.afterPropertiesSet(); 149 return dao; 150 } 151 152 @Override 153 protected JobInstanceDao createJobInstanceDao() throws Exception { 154 JdbcJobInstanceDao dao = new JdbcJobInstanceDao(); 155 dao.setJdbcTemplate(jdbcOperations); 156 dao.setJobIncrementer(incrementer); 157 dao.setTablePrefix(tablePrefix); 158 dao.afterPropertiesSet(); 159 return dao; 160 } 161 162 @Override 163 protected JobExecutionDao createJobExecutionDao() throws Exception { 164 JdbcJobExecutionDao dao = new JdbcJobExecutionDao(); 165 dao.setJdbcTemplate(jdbcOperations); 166 dao.setJobExecutionIncrementer(incrementer); 167 dao.setTablePrefix(tablePrefix); 168 dao.afterPropertiesSet(); 169 return dao; 170 } 171 172 @Override 173 protected StepExecutionDao createStepExecutionDao() throws Exception { 174 JdbcStepExecutionDao dao = new JdbcStepExecutionDao(); 175 dao.setJdbcTemplate(jdbcOperations); 176 dao.setStepExecutionIncrementer(incrementer); 177 dao.setTablePrefix(tablePrefix); 178 dao.afterPropertiesSet(); 179 return dao; 180 } 181 182 @Override 183 public JobExplorer getObject() throws Exception { 184 return getTarget(); 185 } 186}