001/* 002 * Copyright 2013-2018 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 */ 016package org.springframework.batch.core.jsr; 017 018import java.util.Map; 019import java.util.Properties; 020 021import javax.sql.DataSource; 022 023import org.springframework.batch.core.JobParameter; 024import org.springframework.batch.core.JobParameters; 025import org.springframework.batch.core.JobParametersBuilder; 026import org.springframework.batch.core.converter.JobParametersConverter; 027import org.springframework.batch.core.repository.JobRepository; 028import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao; 029import org.springframework.batch.item.database.support.DataFieldMaxValueIncrementerFactory; 030import org.springframework.batch.item.database.support.DefaultDataFieldMaxValueIncrementerFactory; 031import org.springframework.batch.support.DatabaseType; 032import org.springframework.beans.factory.InitializingBean; 033import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; 034import org.springframework.lang.Nullable; 035import org.springframework.util.Assert; 036 037/** 038 * Provides default conversion methodology for JSR-352's implementation. 039 * 040 * Since Spring Batch uses job parameters as a way of identifying a job 041 * instance, this converter will add an additional identifying parameter if 042 * it does not exist already in the list. The id for the identifying parameter 043 * will come from the JOB_SEQ sequence as used to generate the unique ids 044 * for BATCH_JOB_INSTANCE records. 045 * 046 * @author Michael Minella 047 * @author Mahmoud Ben Hassine 048 * @since 3.0 049 */ 050public class JsrJobParametersConverter implements JobParametersConverter, InitializingBean { 051 052 public static final String JOB_RUN_ID = "jsr_batch_run_id"; 053 public DataFieldMaxValueIncrementer incrementer; 054 public String tablePrefix = AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX; 055 public DataSource dataSource; 056 057 /** 058 * Main constructor. 059 * 060 * @param dataSource used to gain access to the database to get unique ids. 061 */ 062 public JsrJobParametersConverter(DataSource dataSource) { 063 Assert.notNull(dataSource, "A DataSource is required"); 064 this.dataSource = dataSource; 065 } 066 067 /** 068 * The table prefix used in the current {@link JobRepository} 069 * 070 * @param tablePrefix the table prefix used for the job repository tables 071 */ 072 public void setTablePrefix(String tablePrefix) { 073 this.tablePrefix = tablePrefix; 074 } 075 076 @Override 077 public void afterPropertiesSet() throws Exception { 078 DataFieldMaxValueIncrementerFactory factory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource); 079 080 this.incrementer = factory.getIncrementer(DatabaseType.fromMetaData(dataSource).name(), tablePrefix + "JOB_SEQ"); 081 } 082 083 /* (non-Javadoc) 084 * @see org.springframework.batch.core.converter.JobParametersConverter#getJobParameters(java.util.Properties) 085 */ 086 @Override 087 public JobParameters getJobParameters(@Nullable Properties properties) { 088 JobParametersBuilder builder = new JobParametersBuilder(); 089 boolean runIdFound = false; 090 091 if(properties != null) { 092 for (Map.Entry<Object, Object> curParameter : properties.entrySet()) { 093 if(curParameter.getValue() != null) { 094 if(curParameter.getKey().equals(JOB_RUN_ID)) { 095 runIdFound = true; 096 builder.addLong(curParameter.getKey().toString(), Long.valueOf((String) curParameter.getValue()), true); 097 } else { 098 builder.addString(curParameter.getKey().toString(), curParameter.getValue().toString(), false); 099 } 100 } 101 } 102 } 103 104 if(!runIdFound) { 105 builder.addLong(JOB_RUN_ID, incrementer.nextLongValue()); 106 } 107 108 return builder.toJobParameters(); 109 } 110 111 /* (non-Javadoc) 112 * @see org.springframework.batch.core.converter.JobParametersConverter#getProperties(org.springframework.batch.core.JobParameters) 113 */ 114 @Override 115 public Properties getProperties(@Nullable JobParameters params) { 116 Properties properties = new Properties(); 117 boolean runIdFound = false; 118 119 if(params != null) { 120 for(Map.Entry<String, JobParameter> curParameter: params.getParameters().entrySet()) { 121 if(curParameter.getKey().equals(JOB_RUN_ID)) { 122 runIdFound = true; 123 } 124 125 properties.setProperty(curParameter.getKey(), curParameter.getValue().getValue().toString()); 126 } 127 } 128 129 if(!runIdFound) { 130 properties.setProperty(JOB_RUN_ID, String.valueOf(incrementer.nextLongValue())); 131 } 132 133 return properties; 134 } 135}