[BATCH-383] Fixes to make Spring Batch 1.4 runtime compliant.
This commit is contained in:
@@ -40,11 +40,12 @@ public class ScheduledJobParametersFactory implements JobParametersConverter {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.batch.core.runtime.JobParametersFactory#getJobParameters(java.util.Properties)
|
||||
*/
|
||||
public JobParameters getJobParameters(Properties props) {
|
||||
|
||||
if(props == null || props.isEmpty()){
|
||||
if (props == null || props.isEmpty()) {
|
||||
return new JobParameters();
|
||||
}
|
||||
|
||||
@@ -56,14 +57,11 @@ public class ScheduledJobParametersFactory implements JobParametersConverter {
|
||||
Date scheduleDate;
|
||||
try {
|
||||
scheduleDate = dateFormat.parse(entry.getValue().toString());
|
||||
}
|
||||
catch (ParseException ex) {
|
||||
throw new IllegalArgumentException("Date format is invalid: [" + entry.getValue() + "]",
|
||||
ex);
|
||||
} catch (ParseException ex) {
|
||||
throw new IllegalArgumentException("Date format is invalid: [" + entry.getValue() + "]");
|
||||
}
|
||||
propertiesBuilder.addDate(entry.getKey().toString(), scheduleDate);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
propertiesBuilder.addString(entry.getKey().toString(), entry.getValue().toString());
|
||||
}
|
||||
}
|
||||
@@ -72,17 +70,16 @@ public class ScheduledJobParametersFactory implements JobParametersConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert schedule date to Date, and assume all other parameters can be
|
||||
* represented by their default string value.
|
||||
* Convert schedule date to Date, and assume all other parameters can be represented by their default string value.
|
||||
*
|
||||
* @see org.springframework.batch.core.support.JobParametersConverter#getProperties(org.springframework.batch.core.JobParameters)
|
||||
*/
|
||||
public Properties getProperties(JobParameters params) {
|
||||
|
||||
if(params == null || params.isEmpty()){
|
||||
|
||||
if (params == null || params.isEmpty()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
|
||||
Map parameters = params.getParameters();
|
||||
Properties result = new Properties();
|
||||
for (Iterator iterator = parameters.keySet().iterator(); iterator.hasNext();) {
|
||||
@@ -91,7 +88,7 @@ public class ScheduledJobParametersFactory implements JobParametersConverter {
|
||||
if (key.equals(SCHEDULE_DATE_KEY)) {
|
||||
result.setProperty(key, dateFormat.format(value));
|
||||
} else {
|
||||
result.setProperty(key,""+value);
|
||||
result.setProperty(key, "" + value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -99,6 +96,7 @@ public class ScheduledJobParametersFactory implements JobParametersConverter {
|
||||
|
||||
/**
|
||||
* Public setter for injecting a date format.
|
||||
*
|
||||
* @param dateFormat a {@link DateFormat}, defaults to "yyyy/MM/dd"
|
||||
*/
|
||||
public void setDateFormat(DateFormat dateFormat) {
|
||||
|
||||
@@ -31,9 +31,8 @@ import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Converter for {@link JobParameters} instances using a simple naming convention
|
||||
* for property keys. Key names ending with "(<type>)" where type is one
|
||||
* of string, date, long are converted to the corresponding type. The default
|
||||
* Converter for {@link JobParameters} instances using a simple naming convention for property keys. Key names ending
|
||||
* with "(<type>)" where type is one of string, date, long are converted to the corresponding type. The default
|
||||
* type is string. E.g.
|
||||
*
|
||||
* <pre>
|
||||
@@ -41,8 +40,8 @@ import org.springframework.util.StringUtils;
|
||||
* department.id(long)=2345
|
||||
* </pre>
|
||||
*
|
||||
* The literal values are converted to the correct type using the default Spring
|
||||
* strategies, augmented if necessary by the custom editors provided.
|
||||
* The literal values are converted to the correct type using the default Spring strategies, augmented if necessary by
|
||||
* the custom editors provided.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -60,11 +59,10 @@ public class DefaultJobParametersConverter implements JobParametersConverter {
|
||||
private NumberFormat numberFormat = new DecimalFormat("#");
|
||||
|
||||
/**
|
||||
* Check for suffix on keys and use those to decide how to convert the
|
||||
* value.
|
||||
* Check for suffix on keys and use those to decide how to convert the value.
|
||||
*
|
||||
* @throws IllegalArgumentException if a number or date is passed in that
|
||||
* cannot be parsed, or cast to the correct type.
|
||||
* @throws IllegalArgumentException if a number or date is passed in that cannot be parsed, or cast to the correct
|
||||
* type.
|
||||
*
|
||||
* @see org.springframework.batch.core.support.JobParametersConverter#getJobParameters(java.util.Properties)
|
||||
*/
|
||||
@@ -84,35 +82,28 @@ public class DefaultJobParametersConverter implements JobParametersConverter {
|
||||
Date date;
|
||||
try {
|
||||
date = dateFormat.parse(value);
|
||||
}
|
||||
catch (ParseException ex) {
|
||||
} catch (ParseException ex) {
|
||||
String suffix = (dateFormat instanceof SimpleDateFormat) ? ", use "
|
||||
+ ((SimpleDateFormat) dateFormat).toPattern() : "";
|
||||
throw new IllegalArgumentException("Date format is invalid: [" + value + "]" + suffix, ex);
|
||||
+ ((SimpleDateFormat) dateFormat).toPattern() : "";
|
||||
throw new IllegalArgumentException("Date format is invalid: [" + value + "]" + suffix);
|
||||
}
|
||||
propertiesBuilder.addDate(StringUtils.replace(key, DATE_TYPE, ""), date);
|
||||
}
|
||||
else if (key.endsWith(LONG_TYPE)) {
|
||||
} else if (key.endsWith(LONG_TYPE)) {
|
||||
Long result;
|
||||
try {
|
||||
result = (Long) numberFormat.parse(value);
|
||||
}
|
||||
catch (ParseException ex) {
|
||||
} catch (ParseException ex) {
|
||||
String suffix = (numberFormat instanceof DecimalFormat) ? ", use "
|
||||
+ ((DecimalFormat) numberFormat).toPattern() : "";
|
||||
throw new IllegalArgumentException(
|
||||
"Number format is invalid: [" + value + "], use " + suffix, ex);
|
||||
}
|
||||
catch (ClassCastException ex) {
|
||||
+ ((DecimalFormat) numberFormat).toPattern() : "";
|
||||
throw new IllegalArgumentException("Number format is invalid: [" + value + "], use " + suffix);
|
||||
} catch (ClassCastException ex) {
|
||||
throw new IllegalArgumentException("Number format is invalid: [" + value
|
||||
+ "], use a format with no decimal places", ex);
|
||||
+ "], use a format with no decimal places");
|
||||
}
|
||||
propertiesBuilder.addLong(StringUtils.replace(key, LONG_TYPE, ""), result);
|
||||
}
|
||||
else if (StringUtils.endsWithIgnoreCase(key, STRING_TYPE)) {
|
||||
} else if (StringUtils.endsWithIgnoreCase(key, STRING_TYPE)) {
|
||||
propertiesBuilder.addString(StringUtils.replace(key, STRING_TYPE, ""), value);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
propertiesBuilder.addString(key.toString(), value.toString());
|
||||
}
|
||||
}
|
||||
@@ -121,8 +112,7 @@ public class DefaultJobParametersConverter implements JobParametersConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the same suffixes to create properties (omitting the string suffix
|
||||
* because it is the default).
|
||||
* Use the same suffixes to create properties (omitting the string suffix because it is the default).
|
||||
*
|
||||
* @see org.springframework.batch.core.support.JobParametersConverter#getProperties(org.springframework.batch.core.JobParameters)
|
||||
*/
|
||||
@@ -139,11 +129,9 @@ public class DefaultJobParametersConverter implements JobParametersConverter {
|
||||
Object value = parameters.get(key);
|
||||
if (value instanceof Date) {
|
||||
result.setProperty(key + DATE_TYPE, dateFormat.format(value));
|
||||
}
|
||||
else if (value instanceof Long) {
|
||||
} else if (value instanceof Long) {
|
||||
result.setProperty(key + LONG_TYPE, numberFormat.format(value));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
result.setProperty(key, "" + value);
|
||||
}
|
||||
}
|
||||
@@ -152,6 +140,7 @@ public class DefaultJobParametersConverter implements JobParametersConverter {
|
||||
|
||||
/**
|
||||
* Public setter for injecting a date format.
|
||||
*
|
||||
* @param dateFormat a {@link DateFormat}, defaults to "yyyy/MM/dd"
|
||||
*/
|
||||
public void setDateFormat(DateFormat dateFormat) {
|
||||
@@ -159,8 +148,8 @@ public class DefaultJobParametersConverter implements JobParametersConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link NumberFormat}. Used to parse longs, so must
|
||||
* not contain decimal place (e.g. use "#" or "#,###").
|
||||
* Public setter for the {@link NumberFormat}. Used to parse longs, so must not contain decimal place (e.g. use "#"
|
||||
* or "#,###").
|
||||
*
|
||||
* @param numberFormat the {@link NumberFormat} to set
|
||||
*/
|
||||
|
||||
@@ -199,7 +199,7 @@ public class JobParametersTests extends TestCase {
|
||||
public void testToStringOrder() {
|
||||
|
||||
Map props = parameters.getParameters();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
StringBuffer stringBuilder = new StringBuffer();
|
||||
for (Iterator it = props.entrySet().iterator(); it.hasNext();) {
|
||||
Entry entry = (Entry) it.next();
|
||||
stringBuilder.append(entry.toString() + ";");
|
||||
@@ -226,7 +226,7 @@ public class JobParametersTests extends TestCase {
|
||||
JobParameters testProps = new JobParameters(stringMap, longMap, doubleMap, dateMap);
|
||||
|
||||
props = testProps.getParameters();
|
||||
stringBuilder = new StringBuilder();
|
||||
stringBuilder = new StringBuffer();
|
||||
for (Iterator it = props.entrySet().iterator(); it.hasNext();) {
|
||||
Entry entry = (Entry) it.next();
|
||||
stringBuilder.append(entry.toString() + ";");
|
||||
|
||||
@@ -17,11 +17,10 @@ package org.springframework.batch.core.job;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.batch.core.step.StepSupport;
|
||||
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.step.StepSupport;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
@@ -31,8 +30,7 @@ public class AbstractJobTests extends TestCase {
|
||||
JobSupport job = new JobSupport("job");
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.job.AbstractJob#JobConfiguration()}.
|
||||
* Test method for {@link org.springframework.batch.core.job.AbstractJob#JobConfiguration()}.
|
||||
*/
|
||||
public void testJobConfiguration() {
|
||||
job = new JobSupport();
|
||||
@@ -40,8 +38,7 @@ public class AbstractJobTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.job.AbstractJob#setBeanName(java.lang.String)}.
|
||||
* Test method for {@link org.springframework.batch.core.job.AbstractJob#setBeanName(java.lang.String)}.
|
||||
*/
|
||||
public void testSetBeanName() {
|
||||
job.setBeanName("foo");
|
||||
@@ -49,8 +46,7 @@ public class AbstractJobTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.job.AbstractJob#setBeanName(java.lang.String)}.
|
||||
* Test method for {@link org.springframework.batch.core.job.AbstractJob#setBeanName(java.lang.String)}.
|
||||
*/
|
||||
public void testSetBeanNameWithNullName() {
|
||||
job = new JobSupport(null);
|
||||
@@ -60,8 +56,7 @@ public class AbstractJobTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.job.AbstractJob#setStepNames(java.util.List)}.
|
||||
* Test method for {@link org.springframework.batch.core.job.AbstractJob#setStepNames(java.util.List)}.
|
||||
*/
|
||||
public void testSetSteps() {
|
||||
job.setSteps(Collections.singletonList(new StepSupport("step")));
|
||||
@@ -78,8 +73,7 @@ public class AbstractJobTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.job.AbstractJob#setStartLimit(int)}.
|
||||
* Test method for {@link org.springframework.batch.core.job.AbstractJob#setStartLimit(int)}.
|
||||
*/
|
||||
public void testSetStartLimit() {
|
||||
assertEquals(Integer.MAX_VALUE, job.getStartLimit());
|
||||
@@ -88,28 +82,30 @@ public class AbstractJobTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.job.AbstractJob#setRestartable(boolean)}.
|
||||
* Test method for {@link org.springframework.batch.core.job.AbstractJob#setRestartable(boolean)}.
|
||||
*/
|
||||
public void testSetRestartable() {
|
||||
assertFalse(job.isRestartable());
|
||||
job.setRestartable(true);
|
||||
assertTrue(job.isRestartable());
|
||||
}
|
||||
|
||||
|
||||
public void testToString() throws Exception {
|
||||
String value = job.toString();
|
||||
assertTrue("Should contain name: "+value, value.indexOf("name=")>=0);
|
||||
assertTrue("Should contain name: " + value, value.indexOf("name=") >= 0);
|
||||
}
|
||||
|
||||
|
||||
public void testRunNotSupported() throws Exception {
|
||||
try {
|
||||
job.execute(null);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// expected
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain JobSupport: "+message, message.contains("JobSupport"));
|
||||
assertTrue("Message should contain JobSupport: " + message, contains(message, "JobSupport"));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,8 +98,7 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
try {
|
||||
testRun();
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("foo", e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -114,8 +113,7 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
try {
|
||||
testRun();
|
||||
fail("Expected Error");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("foo", e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
@@ -124,11 +122,10 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
try {
|
||||
new SimpleJobLauncher().afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
} catch (IllegalStateException e) {
|
||||
// expected
|
||||
assertTrue("Message did not contain repository: " + e.getMessage(), e.getMessage().toLowerCase().contains(
|
||||
"repository"));
|
||||
assertTrue("Message did not contain repository: " + e.getMessage(), contains(e.getMessage().toLowerCase(),
|
||||
"repository"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,4 +134,8 @@ public class SimpleJobLauncherTests extends TestCase {
|
||||
jobLauncher.setJobRepository(jobRepository);
|
||||
jobLauncher.afterPropertiesSet(); // no error
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public class ScheduledJobParametersFactoryTests extends TestCase {
|
||||
public void testGetProperties() throws Exception {
|
||||
|
||||
JobParameters parameters = new JobParametersBuilder().addDate("schedule.date", dateFormat.parse("01/23/2008"))
|
||||
.addString("job.key", "myKey").addString("vendor.id", "33243243").toJobParameters();
|
||||
.addString("job.key", "myKey").addString("vendor.id", "33243243").toJobParameters();
|
||||
|
||||
Properties props = factory.getProperties(parameters);
|
||||
assertNotNull(props);
|
||||
@@ -76,12 +76,12 @@ public class ScheduledJobParametersFactoryTests extends TestCase {
|
||||
JobParameters props = factory.getJobParameters(new Properties());
|
||||
assertTrue(props.getParameters().isEmpty());
|
||||
}
|
||||
|
||||
public void testNullArgs(){
|
||||
|
||||
public void testNullArgs() {
|
||||
assertEquals(new JobParameters(), factory.getJobParameters(null));
|
||||
assertEquals(new Properties(), factory.getProperties(null));
|
||||
}
|
||||
|
||||
|
||||
public void testGetParametersWithDateFormat() throws Exception {
|
||||
|
||||
String[] args = new String[] { "schedule.date=2008/23/01" };
|
||||
@@ -101,8 +101,11 @@ public class ScheduledJobParametersFactoryTests extends TestCase {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong date: "+message, message.contains("20080123"));
|
||||
assertTrue("Message should contain wrong date: " + message, contains(message, "20080123"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
private SimpleExportedJobLauncher launcher = new SimpleExportedJobLauncher();
|
||||
|
||||
private MapJobRegistry jobLocator;
|
||||
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
@@ -55,7 +55,8 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException {
|
||||
JobExecution result = new JobExecution(null);
|
||||
StepExecution stepExecution = result.createStepExecution(new StepSupport("stepName"));
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
stepExecution.setExecutionContext(new ExecutionContext(PropertiesConverter
|
||||
.stringToProperties("foo=bar")));
|
||||
list.add(jobParameters);
|
||||
return result;
|
||||
}
|
||||
@@ -67,6 +68,7 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#afterPropertiesSet()}.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAfterPropertiesSet() throws Exception {
|
||||
@@ -74,16 +76,16 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
try {
|
||||
launcher.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message does not contain 'launcher': " + message, message.toLowerCase().contains("joblauncher"));
|
||||
assertTrue("Message does not contain 'launcher': " + message, contains(message.toLowerCase(), "joblauncher"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#afterPropertiesSet()}.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAfterPropertiesSetWithLauncher() throws Exception {
|
||||
@@ -96,16 +98,14 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
try {
|
||||
launcher.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message does not contain 'locator': " + message, message.toLowerCase().contains("joblocator"));
|
||||
assertTrue("Message does not contain 'locator': " + message, contains(message.toLowerCase(), "joblocator"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#getStatistics()}.
|
||||
* Test method for {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#getStatistics()}.
|
||||
*/
|
||||
public void testGetStatistics() {
|
||||
Properties props = launcher.getStatistics();
|
||||
@@ -114,8 +114,8 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#getStatistics()}.
|
||||
* Test method for {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#getStatistics()}.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testGetStatisticsWithContent() throws Exception {
|
||||
@@ -127,8 +127,8 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#isRunning()}.
|
||||
* Test method for {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#isRunning()}.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testIsRunning() throws Exception {
|
||||
@@ -138,8 +138,8 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#isRunning()}.
|
||||
* Test method for {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#isRunning()}.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAlreadyRunning() throws Exception {
|
||||
@@ -150,7 +150,7 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
}
|
||||
});
|
||||
String value = launcher.run("foo");
|
||||
assertTrue("Return value was not an exception: " + value, value.contains("JobExecutionAlreadyRunningException"));
|
||||
assertTrue("Return value was not an exception: " + value, contains(value, "JobExecutionAlreadyRunningException"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,25 +159,27 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
*/
|
||||
public void testRunNonExistentJob() {
|
||||
String value = launcher.run("foo");
|
||||
assertTrue("Return value was not an exception: " + value, value.contains("NoSuchJobException"));
|
||||
assertTrue("Return value was not an exception: " + value, contains(value, "NoSuchJobException"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#run(java.lang.String)}.
|
||||
* @throws Exception
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testRunJobWithParameters() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
String value = launcher.run("foo", "bar=spam,bucket=crap");
|
||||
assertTrue(launcher.isRunning());
|
||||
assertTrue("Return value was not a JobExecution: " + value, value.contains("JobExecution"));
|
||||
assertTrue("Return value was not a JobExecution: " + value, contains(value, "JobExecution"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#run(java.lang.String)}.
|
||||
* @throws Exception
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testRunJobWithParametersAndFactory() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
@@ -185,6 +187,7 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
public JobParameters getJobParameters(Properties properties) {
|
||||
return new JobParametersBuilder().addString("foo", "spam").toJobParameters();
|
||||
}
|
||||
|
||||
public Properties getProperties(JobParameters params) {
|
||||
return null;
|
||||
}
|
||||
@@ -195,9 +198,9 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#stop()}.
|
||||
* @throws Exception
|
||||
* Test method for {@link org.springframework.batch.core.launch.support.SimpleExportedJobLauncher#stop()}.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testStop() throws Exception {
|
||||
jobLocator.register(new ReferenceJobFactory(new JobSupport("foo")));
|
||||
@@ -207,4 +210,7 @@ public class SimpleExportedJobLauncherTests extends TestCase {
|
||||
assertFalse(launcher.isRunning());
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,8 +503,8 @@ public class ItemOrientedStepTests extends TestCase {
|
||||
} catch (JobInterruptedException ex) {
|
||||
assertEquals(BatchStatus.STOPPED, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertTrue("Message does not contain JobInterruptedException: " + msg, msg
|
||||
.contains("JobInterruptedException"));
|
||||
assertTrue("Message does not contain JobInterruptedException: " + msg, contains(msg,
|
||||
"JobInterruptedException"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ public class ItemOrientedStepTests extends TestCase {
|
||||
} catch (UnexpectedJobExecutionException ex) {
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertTrue("Message does not contain ResetFailedException: " + msg, msg.contains("ResetFailedException"));
|
||||
assertTrue("Message does not contain ResetFailedException: " + msg, contains(msg, "ResetFailedException"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
@@ -591,7 +591,7 @@ public class ItemOrientedStepTests extends TestCase {
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertEquals("", msg);
|
||||
msg = ex.getMessage();
|
||||
assertTrue("Message does not contain 'saving': " + msg, msg.contains("saving"));
|
||||
assertTrue("Message does not contain 'saving': " + msg, contains(msg, "saving"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
@@ -620,7 +620,7 @@ public class ItemOrientedStepTests extends TestCase {
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertEquals("", msg);
|
||||
msg = ex.getMessage();
|
||||
assertTrue("Message does not contain 'final': " + msg, msg.contains("final"));
|
||||
assertTrue("Message does not contain 'final': " + msg, contains(msg, "final"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
@@ -648,17 +648,21 @@ public class ItemOrientedStepTests extends TestCase {
|
||||
itemOrientedStep.execute(stepExecution);
|
||||
fail("Expected InfrastructureException");
|
||||
} catch (UnexpectedJobExecutionException ex) {
|
||||
// The job actually completeed, but the streams couldn't be closed.
|
||||
// The job actually completed, but the streams couldn't be closed.
|
||||
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertEquals("", msg);
|
||||
msg = ex.getMessage();
|
||||
assertTrue("Message does not contain 'close': " + msg, msg.contains("close"));
|
||||
assertTrue("Message does not contain 'close': " + msg, contains(msg, "close"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Bar", ex.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
|
||||
private class MockRestartableItemReader extends ItemStreamSupport implements ItemReader, StepListener {
|
||||
|
||||
private boolean getExecutionAttributesCalled = false;
|
||||
|
||||
@@ -27,7 +27,7 @@ public class TaskletStepTests extends TestCase {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
stepExecution = new StepExecution(new StepSupport("stepName"), new JobExecution(new JobInstance(new Long(0L),
|
||||
new JobParameters(), new JobSupport("testJob")), new Long(12)));
|
||||
new JobParameters(), new JobSupport("testJob")), new Long(12)));
|
||||
}
|
||||
|
||||
public void testTaskletMandatory() throws Exception {
|
||||
@@ -35,10 +35,9 @@ public class TaskletStepTests extends TestCase {
|
||||
step.setJobRepository(new JobRepositorySupport());
|
||||
try {
|
||||
step.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain 'tasklet': " + message, message.toLowerCase().contains("tasklet"));
|
||||
assertTrue("Message should contain 'tasklet': " + message, contains(message.toLowerCase(), "tasklet"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +45,9 @@ public class TaskletStepTests extends TestCase {
|
||||
TaskletStep step = new TaskletStep();
|
||||
try {
|
||||
step.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain 'tasklet': " + message, message.toLowerCase().contains("tasklet"));
|
||||
assertTrue("Message should contain 'tasklet': " + message, contains(message.toLowerCase(), "tasklet"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +88,7 @@ public class TaskletStepTests extends TestCase {
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail("Expected BatchCriticalException");
|
||||
}
|
||||
catch (UnexpectedJobExecutionException e) {
|
||||
} catch (UnexpectedJobExecutionException e) {
|
||||
assertEquals("foo", e.getCause().getMessage());
|
||||
}
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
@@ -126,31 +123,27 @@ public class TaskletStepTests extends TestCase {
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
} catch (RuntimeException e) {
|
||||
assertNotNull(stepExecution.getStartTime());
|
||||
assertEquals(ExitStatus.FAILED, stepExecution.getExitStatus());
|
||||
assertNotNull(stepExecution.getEndTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When job is interrupted the {@link JobInterruptedException} should be propagated up.
|
||||
*/
|
||||
public void testJobInterrupted() throws Exception {
|
||||
TaskletStep step = new TaskletStep(
|
||||
new Tasklet(){
|
||||
public ExitStatus execute() throws Exception {
|
||||
throw new JobInterruptedException("Interrupted while executing tasklet");
|
||||
}
|
||||
},
|
||||
new JobRepositorySupport());
|
||||
|
||||
TaskletStep step = new TaskletStep(new Tasklet() {
|
||||
public ExitStatus execute() throws Exception {
|
||||
throw new JobInterruptedException("Interrupted while executing tasklet");
|
||||
}
|
||||
}, new JobRepositorySupport());
|
||||
|
||||
try {
|
||||
step.execute(stepExecution);
|
||||
fail();
|
||||
}
|
||||
catch (JobInterruptedException expected) {
|
||||
} catch (JobInterruptedException expected) {
|
||||
assertEquals("Interrupted while executing tasklet", expected.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -197,4 +190,7 @@ public class TaskletStepTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,8 @@ public class DefaultJobParametersConverterTests extends TestCase {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong date: "+message, message.contains("20080123"));
|
||||
assertTrue("Message should contain format: "+message, message.contains("yyyy/MM/dd"));
|
||||
assertTrue("Message should contain wrong date: " + message, contains(message, "20080123"));
|
||||
assertTrue("Message should contain format: " + message, contains(message, "yyyy/MM/dd"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ public class DefaultJobParametersConverterTests extends TestCase {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong number: "+message, message.contains("foo"));
|
||||
assertTrue("Message should contain format: "+message, message.contains("#"));
|
||||
assertTrue("Message should contain wrong number: " + message, contains(message, "foo"));
|
||||
assertTrue("Message should contain format: " + message, contains(message, "#"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,15 +110,15 @@ public class DefaultJobParametersConverterTests extends TestCase {
|
||||
factory.getJobParameters(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
} catch (IllegalArgumentException e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message should contain wrong number: "+message, message.contains("1.03"));
|
||||
assertTrue("Message should contain 'decimal': "+message, message.contains("decimal"));
|
||||
assertTrue("Message should contain wrong number: " + message, contains(message, "1.03"));
|
||||
assertTrue("Message should contain 'decimal': " + message, contains(message, "decimal"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetProperties() throws Exception {
|
||||
|
||||
JobParameters parameters = new JobParametersBuilder().addDate("schedule.date", dateFormat.parse("01/23/2008"))
|
||||
.addString("job.key", "myKey").addLong("vendor.id", new Long(33243243)).toJobParameters();
|
||||
.addString("job.key", "myKey").addLong("vendor.id", new Long(33243243)).toJobParameters();
|
||||
|
||||
Properties props = factory.getProperties(parameters);
|
||||
assertNotNull(props);
|
||||
@@ -132,9 +132,13 @@ public class DefaultJobParametersConverterTests extends TestCase {
|
||||
JobParameters props = factory.getJobParameters(new Properties());
|
||||
assertTrue(props.getParameters().isEmpty());
|
||||
}
|
||||
|
||||
public void testNullArgs(){
|
||||
|
||||
public void testNullArgs() {
|
||||
assertEquals(new JobParameters(), factory.getJobParameters(null));
|
||||
assertEquals(new Properties(), factory.getProperties(null));
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,27 +29,27 @@ import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.Skippable;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link ItemReader} for reading database records built on top of Hibernate.
|
||||
*
|
||||
* It executes the HQL {@link #queryString} when initialized and iterates over
|
||||
* the result set as {@link #read()} method is called, returning an object
|
||||
* corresponding to current row.
|
||||
* It executes the HQL {@link #queryString} when initialized and iterates over the result set as {@link #read()} method
|
||||
* is called, returning an object corresponding to current row.
|
||||
*
|
||||
* Input source can be configured to use either {@link StatelessSession}
|
||||
* sufficient for simple mappings without the need to cascade to associated
|
||||
* objects or standard hibernate {@link Session} for more advanced mappings or
|
||||
* when caching is desired.
|
||||
* Input source can be configured to use either {@link StatelessSession} sufficient for simple mappings without the need
|
||||
* to cascade to associated objects or standard hibernate {@link Session} for more advanced mappings or when caching is
|
||||
* desired.
|
||||
*
|
||||
* When stateful session is used it will be cleared after successful commit
|
||||
* without being flushed (no inserts or updates are expected).
|
||||
* When stateful session is used it will be cleared after successful commit without being flushed (no inserts or updates
|
||||
* are expected).
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class HibernateCursorItemReader extends ExecutionContextUserSupport implements ItemReader, ItemStream, Skippable, InitializingBean {
|
||||
public class HibernateCursorItemReader extends ExecutionContextUserSupport implements ItemReader, ItemStream,
|
||||
Skippable, InitializingBean {
|
||||
|
||||
private static final String RESTART_DATA_ROW_NUMBER_KEY = "row.number";
|
||||
|
||||
@@ -77,12 +77,11 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
private int currentProcessedRow = 0;
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
|
||||
private boolean saveState = false;
|
||||
|
||||
|
||||
|
||||
public HibernateCursorItemReader() {
|
||||
setName(HibernateCursorItemReader.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(HibernateCursorItemReader.class));
|
||||
}
|
||||
|
||||
public Object read() {
|
||||
@@ -117,8 +116,7 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
skipCount = 0;
|
||||
if (useStatelessSession) {
|
||||
statelessSession.close();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
statefulSession.close();
|
||||
}
|
||||
}
|
||||
@@ -132,20 +130,20 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
if (useStatelessSession) {
|
||||
statelessSession = sessionFactory.openStatelessSession();
|
||||
cursor = statelessSession.createQuery(queryString).scroll();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
statefulSession = sessionFactory.openSession();
|
||||
cursor = statefulSession.createQuery(queryString).scroll();
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
|
||||
if (executionContext.containsKey(getKey(RESTART_DATA_ROW_NUMBER_KEY))) {
|
||||
currentProcessedRow = Integer.parseInt(executionContext.getString(getKey(RESTART_DATA_ROW_NUMBER_KEY)));
|
||||
cursor.setRowNumber(currentProcessedRow - 1);
|
||||
}
|
||||
|
||||
|
||||
if (executionContext.containsKey(getKey(SKIPPED_ROWS))) {
|
||||
String[] skipped = StringUtils.commaDelimitedListToStringArray(executionContext.getString(getKey(SKIPPED_ROWS)));
|
||||
String[] skipped = StringUtils.commaDelimitedListToStringArray(executionContext
|
||||
.getString(getKey(SKIPPED_ROWS)));
|
||||
for (int i = 0; i < skipped.length; i++) {
|
||||
this.skippedRows.add(new Integer(skipped[i]));
|
||||
}
|
||||
@@ -174,9 +172,8 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
/**
|
||||
* Can be set only in uninitialized state.
|
||||
*
|
||||
* @param useStatelessSession <code>true</code> to use
|
||||
* {@link StatelessSession} <code>false</code> to use standard hibernate
|
||||
* {@link Session}
|
||||
* @param useStatelessSession <code>true</code> to use {@link StatelessSession} <code>false</code> to use
|
||||
* standard hibernate {@link Session}
|
||||
*/
|
||||
public void setUseStatelessSession(boolean useStatelessSession) {
|
||||
Assert.state(!initialized);
|
||||
@@ -186,7 +183,7 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
/**
|
||||
*/
|
||||
public void update(ExecutionContext executionContext) {
|
||||
if(saveState){
|
||||
if (saveState) {
|
||||
Assert.notNull(executionContext, "ExecutionContext must not be null");
|
||||
executionContext.putString(getKey(RESTART_DATA_ROW_NUMBER_KEY), "" + currentProcessedRow);
|
||||
String skipped = skippedRows.toString();
|
||||
@@ -195,10 +192,8 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip the current row. If the transaction is rolled back, this row will
|
||||
* not be represented when read() is called. For example, if you read in row
|
||||
* 2, find the data to be bad, and call skip(), then continue processing and
|
||||
* find
|
||||
* Skip the current row. If the transaction is rolled back, this row will not be represented when read() is called.
|
||||
* For example, if you read in row 2, find the data to be bad, and call skip(), then continue processing and find
|
||||
*/
|
||||
public void skip() {
|
||||
skippedRows.add(new Integer(currentProcessedRow));
|
||||
@@ -206,10 +201,8 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark is supported as long as this {@link ItemStream} is used in a
|
||||
* single-threaded environment. The state backing the mark is a single
|
||||
* counter, keeping track of the current position, so multiple threads
|
||||
* cannot be accommodated.
|
||||
* Mark is supported as long as this {@link ItemStream} is used in a single-threaded environment. The state backing
|
||||
* the mark is a single counter, keeping track of the current position, so multiple threads cannot be accommodated.
|
||||
*
|
||||
* @see org.springframework.batch.item.ItemReader#mark()
|
||||
*/
|
||||
@@ -222,20 +215,20 @@ public class HibernateCursorItemReader extends ExecutionContextUserSupport impl
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.batch.item.stream.ItemStreamAdapter#reset(org.springframework.batch.item.ExecutionContext)
|
||||
*/
|
||||
public void reset() {
|
||||
currentProcessedRow = lastCommitRowNumber;
|
||||
if (lastCommitRowNumber == 0) {
|
||||
cursor.beforeFirst();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Set the cursor so that next time it is advanced it will
|
||||
// come back to the committed row.
|
||||
cursor.setRowNumber(lastCommitRowNumber - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setSaveState(boolean saveState) {
|
||||
this.saveState = saveState;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLExceptionTranslator;
|
||||
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -143,7 +144,7 @@ public class JdbcCursorItemReader extends ExecutionContextUserSupport implements
|
||||
private boolean saveState = false;
|
||||
|
||||
public JdbcCursorItemReader() {
|
||||
setName(JdbcCursorItemReader.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(JdbcCursorItemReader.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.springframework.batch.item.database.DrivingQueryItemReader;
|
||||
import org.springframework.batch.item.database.KeyCollector;
|
||||
import org.springframework.orm.ibatis.SqlMapClientTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.ibatis.sqlmap.client.SqlMapClient;
|
||||
|
||||
@@ -33,7 +34,7 @@ public class IbatisKeyCollector extends ExecutionContextUserSupport implements K
|
||||
private String restartQueryId;
|
||||
|
||||
public IbatisKeyCollector() {
|
||||
setName(IbatisKeyCollector.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(IbatisKeyCollector.class));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,27 +24,24 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SingleColumnRowMapper;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Jdbc {@link KeyCollector} implementation that only works for a single column
|
||||
* key. A sql query must be passed in which will be used to return a list of
|
||||
* keys. Each key will be mapped by a {@link RowMapper} that returns a mapped
|
||||
* key. By default, the {@link SingleColumnRowMapper} is used, and will convert
|
||||
* keys into well known types at runtime. It is extremely important to note that
|
||||
* only one column should be mapped to an object and returned as a key. If
|
||||
* multiple columns are returned as a key in this strategy, then restart will
|
||||
* not function properly. Instead a strategy that supports keys comprised of
|
||||
* multiple columns should be used.</p>
|
||||
* Jdbc {@link KeyCollector} implementation that only works for a single column key. A sql query must be passed in which
|
||||
* will be used to return a list of keys. Each key will be mapped by a {@link RowMapper} that returns a mapped key. By
|
||||
* default, the {@link SingleColumnRowMapper} is used, and will convert keys into well known types at runtime. It is
|
||||
* extremely important to note that only one column should be mapped to an object and returned as a key. If multiple
|
||||
* columns are returned as a key in this strategy, then restart will not function properly. Instead a strategy that
|
||||
* supports keys comprised of multiple columns should be used.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Restartability: Because the key is only one column, restart is made much more
|
||||
* simple. Before each commit, the last processed key is returned to be stored
|
||||
* as restart data. Upon restart, that same key is given back to restore from,
|
||||
* using a separate 'RestartQuery'. This means that only the keys remaining to
|
||||
* be processed are returned, rather than returning the original list of keys
|
||||
* and iterating forward to that last committed point.
|
||||
* Restartability: Because the key is only one column, restart is made much more simple. Before each commit, the last
|
||||
* processed key is returned to be stored as restart data. Upon restart, that same key is given back to restore from,
|
||||
* using a separate 'RestartQuery'. This means that only the keys remaining to be processed are returned, rather than
|
||||
* returning the original list of keys and iterating forward to that last committed point.
|
||||
* </p>
|
||||
*
|
||||
* @author Lucas Ward
|
||||
@@ -63,12 +60,12 @@ public class SingleColumnJdbcKeyCollector extends ExecutionContextUserSupport im
|
||||
private RowMapper keyMapper = new SingleColumnRowMapper();
|
||||
|
||||
public SingleColumnJdbcKeyCollector() {
|
||||
setName(SingleColumnJdbcKeyCollector.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(SingleColumnJdbcKeyCollector.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance using the provided jdbcTemplate and string
|
||||
* representing the sql statement that should be used to retrieve keys.
|
||||
* Constructs a new instance using the provided jdbcTemplate and string representing the sql statement that should
|
||||
* be used to retrieve keys.
|
||||
*
|
||||
* @param jdbcTemplate
|
||||
* @param sql
|
||||
@@ -85,18 +82,18 @@ public class SingleColumnJdbcKeyCollector extends ExecutionContextUserSupport im
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.batch.io.driving.KeyGenerationStrategy#retrieveKeys()
|
||||
*/
|
||||
public List retrieveKeys(ExecutionContext executionContext) {
|
||||
|
||||
|
||||
Assert.notNull(executionContext, "The ExecutionContext must not be null");
|
||||
|
||||
if (executionContext.containsKey(RESTART_KEY)) {
|
||||
Assert.state(StringUtils.hasText(restartSql), "The restart sql query must not be null or empty"
|
||||
+ " in order to restart.");
|
||||
+ " in order to restart.");
|
||||
return jdbcTemplate.query(restartSql, new Object[] { executionContext.get(RESTART_KEY) }, keyMapper);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
return jdbcTemplate.query(sql, keyMapper);
|
||||
}
|
||||
}
|
||||
@@ -115,6 +112,7 @@ public class SingleColumnJdbcKeyCollector extends ExecutionContextUserSupport im
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@@ -132,8 +130,7 @@ public class SingleColumnJdbcKeyCollector extends ExecutionContextUserSupport im
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the SQL query to be used to return the remaining keys to be
|
||||
* processed.
|
||||
* Set the SQL query to be used to return the remaining keys to be processed.
|
||||
*
|
||||
* @param restartSql
|
||||
*/
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.springframework.batch.item.file.transform.LineTokenizer;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* This class represents a {@link ItemReader}, that reads lines from text file, tokenizes them to structured tuples ({@link FieldSet}s)
|
||||
@@ -100,7 +101,7 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
|
||||
private LineReader reader;
|
||||
|
||||
public FlatFileItemReader() {
|
||||
setName(FlatFileItemReader.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(FlatFileItemReader.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,9 +259,8 @@ public class FlatFileItemReader extends ExecutionContextUserSupport implements I
|
||||
throw e;
|
||||
} catch (ItemReaderException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* This class is an output target that writes data to a file or stream. The writer also provides restart, statistics and
|
||||
@@ -81,7 +82,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implements I
|
||||
private FieldSetCreator fieldSetCreator;
|
||||
|
||||
public FlatFileItemWriter() {
|
||||
setName(FlatFileItemWriter.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(FlatFileItemWriter.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -96,12 +96,12 @@ public class RecursiveCollectionItemTransformer implements ItemTransformer {
|
||||
|
||||
private static class TransformHolder {
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StringBuffer builder = new StringBuffer();
|
||||
|
||||
TransformHolder() {
|
||||
}
|
||||
|
||||
TransformHolder(StringBuilder builder) {
|
||||
TransformHolder(StringBuffer builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,19 +26,19 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Input source for reading XML input based on StAX.
|
||||
*
|
||||
* It extracts fragments from the input XML document which correspond to records
|
||||
* for processing. The fragments are wrapped with StartDocument and EndDocument
|
||||
* events so that the fragments can be further processed like standalone XML
|
||||
* It extracts fragments from the input XML document which correspond to records for processing. The fragments are
|
||||
* wrapped with StartDocument and EndDocument events so that the fragments can be further processed like standalone XML
|
||||
* documents.
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class StaxEventItemReader extends ExecutionContextUserSupport implements ItemReader, Skippable, ItemStream,
|
||||
InitializingBean {
|
||||
InitializingBean {
|
||||
|
||||
private static final String READ_COUNT_STATISTICS_NAME = "read.count";
|
||||
|
||||
@@ -61,13 +61,13 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
private long currentRecordCount = 0;
|
||||
|
||||
private List skipRecords = new ArrayList();
|
||||
|
||||
|
||||
private boolean saveState = false;
|
||||
|
||||
|
||||
public StaxEventItemReader() {
|
||||
setName(StaxEventItemReader.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(StaxEventItemReader.class));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read in the next root element from the file, and return it.
|
||||
*
|
||||
@@ -103,14 +103,11 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
try {
|
||||
fragmentReader.close();
|
||||
inputStream.close();
|
||||
}
|
||||
catch (XMLStreamException e) {
|
||||
} catch (XMLStreamException e) {
|
||||
throw new DataAccessResourceFailureException("Error while closing event reader", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new DataAccessResourceFailureException("Error while closing input stream", e);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
fragmentReader = null;
|
||||
inputStream = null;
|
||||
}
|
||||
@@ -122,17 +119,15 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
try {
|
||||
inputStream = resource.getInputStream();
|
||||
txReader = new DefaultTransactionalEventReader(XMLInputFactory.newInstance().createXMLEventReader(
|
||||
inputStream));
|
||||
inputStream));
|
||||
fragmentReader = new DefaultFragmentEventReader(txReader);
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
} catch (XMLStreamException xse) {
|
||||
throw new DataAccessResourceFailureException("Unable to create XML reader", xse);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
} catch (IOException ioe) {
|
||||
throw new DataAccessResourceFailureException("Unable to get input stream", ioe);
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
|
||||
if (executionContext.containsKey(getKey(READ_COUNT_STATISTICS_NAME))) {
|
||||
long restoredRecordCount = executionContext.getLong(getKey(READ_COUNT_STATISTICS_NAME));
|
||||
int REASONABLE_ADHOC_COMMIT_FREQUENCY = 100;
|
||||
@@ -156,24 +151,22 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
}
|
||||
|
||||
/**
|
||||
* @param eventReaderDeserializer maps xml fragments corresponding to
|
||||
* records to objects
|
||||
* @param eventReaderDeserializer maps xml fragments corresponding to records to objects
|
||||
*/
|
||||
public void setFragmentDeserializer(EventReaderDeserializer eventReaderDeserializer) {
|
||||
this.eventReaderDeserializer = eventReaderDeserializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fragmentRootElementName name of the root element of the fragment
|
||||
* TODO String can be ambiguous due to namespaces, use QName?
|
||||
* @param fragmentRootElementName name of the root element of the fragment TODO String can be ambiguous due to
|
||||
* namespaces, use QName?
|
||||
*/
|
||||
public void setFragmentRootElementName(String fragmentRootElementName) {
|
||||
this.fragmentRootElementName = fragmentRootElementName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the last read record as 'skipped', so that I will not be returned
|
||||
* from read() in the case of a rollback.
|
||||
* Mark the last read record as 'skipped', so that I will not be returned from read() in the case of a rollback.
|
||||
*
|
||||
* @see Skippable#skip()
|
||||
*/
|
||||
@@ -182,12 +175,11 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that all required dependencies for the ItemReader to run are
|
||||
* provided after all properties have been set.
|
||||
* Ensure that all required dependencies for the ItemReader to run are provided after all properties have been set.
|
||||
*
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
* @throws IllegalArgumentException if the Resource, FragmentDeserializer or
|
||||
* FragmentRootElementName is null, or if the root element is empty.
|
||||
* @throws IllegalArgumentException if the Resource, FragmentDeserializer or FragmentRootElementName is null, or if
|
||||
* the root element is empty.
|
||||
* @throws IllegalStateException if the Resource does not exist.
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@@ -200,22 +192,19 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
* @see ItemStream#update(ExecutionContext)
|
||||
*/
|
||||
public void update(ExecutionContext executionContext) {
|
||||
if(saveState){
|
||||
if (saveState) {
|
||||
Assert.notNull(executionContext, "ExecutionContext must not be null");
|
||||
executionContext.putLong(getKey(READ_COUNT_STATISTICS_NAME), currentRecordCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for moving the cursor before the StartElement of the fragment
|
||||
* root.
|
||||
* Responsible for moving the cursor before the StartElement of the fragment root.
|
||||
*
|
||||
* This implementation simply looks for the next corresponding element, it
|
||||
* does not care about element nesting. You will need to override this
|
||||
* method to correctly handle composite fragments.
|
||||
* This implementation simply looks for the next corresponding element, it does not care about element nesting. You
|
||||
* will need to override this method to correctly handle composite fragments.
|
||||
*
|
||||
* @return <code>true</code> if next fragment was found,
|
||||
* <code>false</code> otherwise.
|
||||
* @return <code>true</code> if next fragment was found, <code>false</code> otherwise.
|
||||
*/
|
||||
protected boolean moveCursorToNextFragment(XMLEventReader reader) {
|
||||
try {
|
||||
@@ -229,23 +218,19 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
QName startElementName = ((StartElement) reader.peek()).getName();
|
||||
if (startElementName.getLocalPart().equals(fragmentRootElementName)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
reader.nextEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (XMLStreamException e) {
|
||||
} catch (XMLStreamException e) {
|
||||
throw new DataAccessResourceFailureException("Error while reading from event reader", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark is supported as long as this {@link ItemStream} is used in a
|
||||
* single-threaded environment. The state backing the mark is a single
|
||||
* counter, keeping track of the current position, so multiple threads
|
||||
* cannot be accommodated.
|
||||
*
|
||||
* Mark is supported as long as this {@link ItemStream} is used in a single-threaded environment. The state backing
|
||||
* the mark is a single counter, keeping track of the current position, so multiple threads cannot be accommodated.
|
||||
*
|
||||
* @see org.springframework.batch.item.AbstractItemReader#mark()
|
||||
*/
|
||||
public void mark() {
|
||||
@@ -256,6 +241,7 @@ public class StaxEventItemReader extends ExecutionContextUserSupport implements
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.batch.item.ItemStream#reset(org.springframework.batch.item.ExecutionContext)
|
||||
*/
|
||||
public void reset() {
|
||||
|
||||
@@ -27,24 +27,23 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* An implementation of {@link ItemWriter} which uses StAX and
|
||||
* {@link EventWriterSerializer} for serializing object to XML.
|
||||
* An implementation of {@link ItemWriter} which uses StAX and {@link EventWriterSerializer} for serializing object to
|
||||
* XML.
|
||||
*
|
||||
* This item writer also provides restart, statistics and transaction features
|
||||
* by implementing corresponding interfaces.
|
||||
* This item writer also provides restart, statistics and transaction features by implementing corresponding interfaces.
|
||||
*
|
||||
* Output is buffered until {@link #flush()} is called - only then the actual
|
||||
* writing to file takes place.
|
||||
* Output is buffered until {@link #flush()} is called - only then the actual writing to file takes place.
|
||||
*
|
||||
* @author Peter Zozom
|
||||
* @author Robert Kasanicky
|
||||
*
|
||||
*/
|
||||
public class StaxEventItemWriter extends ExecutionContextUserSupport implements ItemWriter, ItemStream,
|
||||
InitializingBean {
|
||||
InitializingBean {
|
||||
|
||||
// default encoding
|
||||
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||
@@ -112,7 +111,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
private List buffer = new ArrayList();
|
||||
|
||||
public StaxEventItemWriter() {
|
||||
setName(StaxEventItemWriter.class.getSimpleName());
|
||||
setName(ClassUtils.getShortName(StaxEventItemWriter.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,8 +178,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tag name of the root element. If not set, default name is used
|
||||
* ("root").
|
||||
* Set the tag name of the root element. If not set, default name is used ("root").
|
||||
*
|
||||
* @param rootTagName the tag name to be used for the root element
|
||||
*/
|
||||
@@ -207,8 +205,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Set "overwrite" flag for the output file. Flag is ignored when output
|
||||
* file processing is restarted.
|
||||
* Set "overwrite" flag for the output file. Flag is ignored when output file processing is restarted.
|
||||
*
|
||||
* @param shouldDeleteIfExists
|
||||
*/
|
||||
@@ -257,8 +254,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
os = new FileOutputStream(file, true);
|
||||
channel = os.getChannel();
|
||||
setPosition(position);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
} catch (IOException ioe) {
|
||||
throw new DataAccessResourceFailureException("Unable to write to file resource: [" + resource + "]", ioe);
|
||||
}
|
||||
|
||||
@@ -270,8 +266,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
if (!restarted) {
|
||||
startDocument(delegateEventWriter);
|
||||
}
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
} catch (XMLStreamException xse) {
|
||||
throw new DataAccessResourceFailureException("Unable to write to file resource: [" + resource + "]", xse);
|
||||
}
|
||||
|
||||
@@ -283,8 +278,8 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
* <li>xml declaration - defines encoding and XML version</li>
|
||||
* <li>opening tag of the root element and its attributes</li>
|
||||
* </ul>
|
||||
* If this is not sufficient for you, simply override this method. Encoding,
|
||||
* version and root tag name can be retrieved with corresponding getters.
|
||||
* If this is not sufficient for you, simply override this method. Encoding, version and root tag name can be
|
||||
* retrieved with corresponding getters.
|
||||
*
|
||||
* @param writer XML event writer
|
||||
* @throws XMLStreamException
|
||||
@@ -312,8 +307,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the XML document. It closes any start tag and writes
|
||||
* corresponding end tags.
|
||||
* Finishes the XML document. It closes any start tag and writes corresponding end tags.
|
||||
*
|
||||
* @param writer XML event writer
|
||||
* @throws XMLStreamException
|
||||
@@ -326,8 +320,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
ByteBuffer bbuf = ByteBuffer.wrap(("</" + getRootTagName() + ">").getBytes());
|
||||
try {
|
||||
channel.write(bbuf);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
} catch (IOException ioe) {
|
||||
throw new DataAccessResourceFailureException("Unable to close file resource: [" + resource + "]", ioe);
|
||||
}
|
||||
}
|
||||
@@ -343,11 +336,9 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
endDocument(delegateEventWriter);
|
||||
eventWriter.close();
|
||||
channel.close();
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
} catch (XMLStreamException xse) {
|
||||
throw new DataAccessResourceFailureException("Unable to close file resource: [" + resource + "]", xse);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
} catch (IOException ioe) {
|
||||
throw new DataAccessResourceFailureException("Unable to close file resource: [" + resource + "]", ioe);
|
||||
}
|
||||
}
|
||||
@@ -359,13 +350,14 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
* @see #flush()
|
||||
*/
|
||||
public void write(Object item) {
|
||||
|
||||
|
||||
currentRecordCount++;
|
||||
buffer.add(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the restart data.
|
||||
*
|
||||
* @see org.springframework.batch.item.ItemStream#update(ExecutionContext)
|
||||
*/
|
||||
public void update(ExecutionContext executionContext) {
|
||||
@@ -378,8 +370,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the actual position in file channel. This method flushes any buffered
|
||||
* data before position is read.
|
||||
* Get the actual position in file channel. This method flushes any buffered data before position is read.
|
||||
*
|
||||
* @return byte offset in file channel
|
||||
*/
|
||||
@@ -390,8 +381,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
try {
|
||||
eventWriter.flush();
|
||||
position = channel.position();
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new DataAccessResourceFailureException("Unable to write to file resource: [" + resource + "]", e);
|
||||
}
|
||||
|
||||
@@ -407,11 +397,10 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implements
|
||||
|
||||
try {
|
||||
Assert.state(channel.size() >= lastCommitPointPosition,
|
||||
"Current file size is smaller than size at last commit");
|
||||
"Current file size is smaller than size at last commit");
|
||||
channel.truncate(newPosition);
|
||||
channel.position(newPosition);
|
||||
}
|
||||
catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
throw new DataAccessResourceFailureException("Unable to write to file resource: [" + resource + "]", e);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ public class LogOrRethrowExceptionHandler implements ExceptionHandler {
|
||||
DefaultExceptionHandler.rethrow(throwable);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Unclassified exception encountered. Did you mean to classifiy this as 'rethrow'?", throwable);
|
||||
"Unclassified exception encountered. Did you mean to classifiy this as 'rethrow'?");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,14 +28,11 @@ import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link MethodInterceptor} that can be used to automatically repeat calls to
|
||||
* a method on a service. The injected {@link RepeatOperations} is used to
|
||||
* control the completion of the loop. By default it will repeat until the
|
||||
* target method returns null. Be careful when injecting a bespoke
|
||||
* {@link RepeatOperations} that the loop will actually terminate, because the
|
||||
* default policy for a vanilla {@link RepeatTemplate} will never complete if
|
||||
* the return type of the target method is void (the value returned is always
|
||||
* not-null, representing the {@link Void#TYPE}).
|
||||
* A {@link MethodInterceptor} that can be used to automatically repeat calls to a method on a service. The injected
|
||||
* {@link RepeatOperations} is used to control the completion of the loop. By default it will repeat until the target
|
||||
* method returns null. Be careful when injecting a bespoke {@link RepeatOperations} that the loop will actually
|
||||
* terminate, because the default policy for a vanilla {@link RepeatTemplate} will never complete if the return type of
|
||||
* the target method is void (the value returned is always not-null, representing the {@link Void#TYPE}).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -47,8 +44,7 @@ public class RepeatOperationsInterceptor implements MethodInterceptor {
|
||||
* Setter for the {@link RepeatOperations}.
|
||||
*
|
||||
* @param batchTempate
|
||||
* @throws IllegalArgumentException
|
||||
* if the argument is null.
|
||||
* @throws IllegalArgumentException if the argument is null.
|
||||
*/
|
||||
public void setRepeatOperations(RepeatOperations batchTempate) {
|
||||
Assert.notNull(batchTempate, "'repeatOperations' cannot be null.");
|
||||
@@ -56,8 +52,8 @@ public class RepeatOperationsInterceptor implements MethodInterceptor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the proceeding method call repeatedly, according to the properties
|
||||
* of the injected {@link RepeatOperations}.
|
||||
* Invoke the proceeding method call repeatedly, according to the properties of the injected
|
||||
* {@link RepeatOperations}.
|
||||
*
|
||||
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
|
||||
*/
|
||||
@@ -65,22 +61,19 @@ public class RepeatOperationsInterceptor implements MethodInterceptor {
|
||||
|
||||
repeatOperations.iterate(new RepeatCallback() {
|
||||
|
||||
public ExitStatus doInIteration(RepeatContext context)
|
||||
throws Exception {
|
||||
public ExitStatus doInIteration(RepeatContext context) throws Exception {
|
||||
try {
|
||||
|
||||
MethodInvocation clone = invocation;
|
||||
if (invocation instanceof ProxyMethodInvocation) {
|
||||
clone = ((ProxyMethodInvocation) invocation)
|
||||
.invocableClone();
|
||||
clone = ((ProxyMethodInvocation) invocation).invocableClone();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"MethodInvocation of the wrong type detected - this should not happen with Spring AOP, so please raise an issue if you see this exception");
|
||||
"MethodInvocation of the wrong type detected - this should not happen with Spring AOP, so please raise an issue if you see this exception");
|
||||
}
|
||||
|
||||
// N.B. discards return value if there is one
|
||||
if (clone.getMethod().getGenericReturnType().equals(
|
||||
Void.TYPE)) {
|
||||
if (clone.getMethod().getReturnType().equals(Void.TYPE)) {
|
||||
clone.proceed();
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
@@ -89,8 +82,7 @@ public class RepeatOperationsInterceptor implements MethodInterceptor {
|
||||
if (e instanceof Exception) {
|
||||
throw (Exception) e;
|
||||
} else {
|
||||
throw new RepeatException(
|
||||
"Unexpected error in batch interceptor", e);
|
||||
throw new RepeatException("Unexpected error in batch interceptor", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,11 @@ import org.springframework.util.PropertiesPersister;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility to convert a Properties object to a String and back. Ideally this
|
||||
* utility should have been used to convert to string in order to convert that
|
||||
* string back to a Properties Object. Attempting to convert a string obtained
|
||||
* by calling Properties.toString() will return an invalid Properties object.
|
||||
* The format of Properties is that used by {@link PropertiesPersister} from the
|
||||
* Spring Core, so a String in the correct format for a Spring property editor
|
||||
* is fine (key=value pairs separated by new lines).
|
||||
* Utility to convert a Properties object to a String and back. Ideally this utility should have been used to convert to
|
||||
* string in order to convert that string back to a Properties Object. Attempting to convert a string obtained by
|
||||
* calling Properties.toString() will return an invalid Properties object. The format of Properties is that used by
|
||||
* {@link PropertiesPersister} from the Spring Core, so a String in the correct format for a Spring property editor is
|
||||
* fine (key=value pairs separated by new lines).
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @author Dave Syer
|
||||
@@ -48,11 +46,9 @@ public final class PropertiesConverter {
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a String to a Properties object. If string is null, an empty
|
||||
* Properties object will be returned. The input String is a set of
|
||||
* name=value pairs, delimited by either newline or comma (for brevity). If
|
||||
* the input String contains a newline it is assumed that the separator is
|
||||
* newline, otherwise comma.
|
||||
* Parse a String to a Properties object. If string is null, an empty Properties object will be returned. The input
|
||||
* String is a set of name=value pairs, delimited by either newline or comma (for brevity). If the input String
|
||||
* contains a newline it is assumed that the separator is newline, otherwise comma.
|
||||
*
|
||||
* @param stringToParse String to parse.
|
||||
* @return Properties parsed from each string.
|
||||
@@ -65,9 +61,9 @@ public final class PropertiesConverter {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
if (!stringToParse.contains("\n")) {
|
||||
if (!contains(stringToParse, "\n")) {
|
||||
return StringUtils.splitArrayElementsIntoProperties(StringUtils
|
||||
.commaDelimitedListToStringArray(stringToParse), "=");
|
||||
.commaDelimitedListToStringArray(stringToParse), "=");
|
||||
}
|
||||
|
||||
StringReader stringReader = new StringReader(stringToParse);
|
||||
@@ -78,20 +74,18 @@ public final class PropertiesConverter {
|
||||
propertiesPersister.load(properties, stringReader);
|
||||
// Exception is only thrown by StringReader after it is closed,
|
||||
// so never in this case.
|
||||
}
|
||||
catch (IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
throw new IllegalStateException("Error while trying to parse String to java.util.Properties,"
|
||||
+ " given String: " + properties);
|
||||
+ " given String: " + properties);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Properties object to String. This is only necessary for
|
||||
* compatibility with converting the String back to a properties object. If
|
||||
* an empty properties object is passed in, a blank string is returned,
|
||||
* otherwise it's string representation is returned.
|
||||
* Convert Properties object to String. This is only necessary for compatibility with converting the String back to
|
||||
* a properties object. If an empty properties object is passed in, a blank string is returned, otherwise it's
|
||||
* string representation is returned.
|
||||
*
|
||||
* @param propertiesToParse
|
||||
* @return String representation of properties object
|
||||
@@ -108,12 +102,15 @@ public final class PropertiesConverter {
|
||||
|
||||
try {
|
||||
propertiesPersister.store(propertiesToParse, stringWriter, null);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
} catch (IOException ex) {
|
||||
// Exception is never thrown by StringWriter
|
||||
throw new IllegalStateException("Error while trying to convert properties to string");
|
||||
}
|
||||
|
||||
return stringWriter.toString();
|
||||
}
|
||||
|
||||
private static boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.batch.item.file.mapping.FieldSetMapper;
|
||||
import org.springframework.batch.item.file.transform.LineTokenizer;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Tests for {@link FlatFileItemReader} - skip and restart functionality.
|
||||
@@ -40,7 +41,7 @@ public class FlatFileItemReaderAdvancedTests extends TestCase {
|
||||
|
||||
// common value used for writing to a file
|
||||
private String TEST_STRING = "FlatFileInputTemplate-TestData";
|
||||
|
||||
|
||||
private ExecutionContext executionContext;
|
||||
|
||||
// simple stub instead of a realistic tokenizer
|
||||
@@ -57,8 +58,7 @@ public class FlatFileItemReaderAdvancedTests extends TestCase {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create inputFile, inject mock/stub dependencies for tested object,
|
||||
* initialize the tested object
|
||||
* Create inputFile, inject mock/stub dependencies for tested object, initialize the tested object
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
@@ -83,6 +83,7 @@ public class FlatFileItemReaderAdvancedTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Test skip and skipRollback functionality
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testSkip() throws Exception {
|
||||
@@ -118,6 +119,7 @@ public class FlatFileItemReaderAdvancedTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Test skip and skipRollback functionality
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testSkipFirstChunk() throws Exception {
|
||||
@@ -160,8 +162,8 @@ public class FlatFileItemReaderAdvancedTests extends TestCase {
|
||||
|
||||
// get restart data
|
||||
reader.update(executionContext);
|
||||
assertEquals(4, executionContext.getLong(
|
||||
FlatFileItemReader.class.getSimpleName() + ".lines.read.count"));
|
||||
assertEquals(4, executionContext.getLong(ClassUtils.getShortName(FlatFileItemReader.class)
|
||||
+ ".lines.read.count"));
|
||||
// close input
|
||||
reader.close(executionContext);
|
||||
|
||||
@@ -175,7 +177,8 @@ public class FlatFileItemReaderAdvancedTests extends TestCase {
|
||||
assertEquals("[testLine6]", reader.read().toString());
|
||||
|
||||
reader.update(executionContext);
|
||||
assertEquals(6, executionContext.getLong(FlatFileItemReader.class.getSimpleName() + ".lines.read.count"));
|
||||
assertEquals(6, executionContext.getLong(ClassUtils.getShortName(FlatFileItemReader.class)
|
||||
+ ".lines.read.count"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Tests for {@link FlatFileItemReader} - the fundamental item reading functionality.
|
||||
*
|
||||
*
|
||||
* @see FlatFileItemReaderAdvancedTests
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@@ -48,7 +48,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
// common value used for writing to a file
|
||||
private String TEST_STRING = "FlatFileInputTemplate-TestData";
|
||||
private String TEST_OUTPUT = "[FlatFileInputTemplate-TestData]";
|
||||
|
||||
|
||||
private ExecutionContext executionContext;
|
||||
|
||||
// simple stub instead of a realistic tokenizer
|
||||
@@ -58,15 +58,14 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
}
|
||||
};
|
||||
|
||||
private FieldSetMapper fieldSetMapper = new FieldSetMapper(){
|
||||
private FieldSetMapper fieldSetMapper = new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
return fs;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create inputFile, inject mock/stub dependencies for tested object,
|
||||
* initialize the tested object
|
||||
* Create inputFile, inject mock/stub dependencies for tested object, initialize the tested object
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
@@ -74,7 +73,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
itemReader.setLineTokenizer(tokenizer);
|
||||
itemReader.setFieldSetMapper(fieldSetMapper);
|
||||
itemReader.afterPropertiesSet();
|
||||
|
||||
|
||||
executionContext = new ExecutionContext();
|
||||
}
|
||||
|
||||
@@ -126,7 +125,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testReadWithMapperError() throws Exception {
|
||||
itemReader.setFieldSetMapper(new FieldSetMapper(){
|
||||
itemReader.setFieldSetMapper(new FieldSetMapper() {
|
||||
public Object mapLine(FieldSet fs) {
|
||||
throw new RuntimeException("foo");
|
||||
}
|
||||
@@ -150,7 +149,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
itemReader.read();
|
||||
fail("Expected ReaderNotOpenException");
|
||||
} catch (ReaderNotOpenException e) {
|
||||
assertTrue(e.getMessage().contains("open"));
|
||||
assertTrue(contains(e.getMessage(), "open"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,8 +168,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
try {
|
||||
itemReader.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -196,8 +194,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
try {
|
||||
itemReader.open(executionContext);
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -209,8 +206,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
try {
|
||||
itemReader.open(executionContext);
|
||||
fail("Expected BatchEnvironmentException");
|
||||
}
|
||||
catch (ItemStreamException e) {
|
||||
} catch (ItemStreamException e) {
|
||||
// expected
|
||||
assertEquals("foo", e.getCause().getMessage());
|
||||
}
|
||||
@@ -227,8 +223,8 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
}
|
||||
|
||||
public void testComments() throws Exception {
|
||||
itemReader.setResource(getInputResource("% Comment\n"+TEST_STRING));
|
||||
itemReader.setComments(new String[] {"%"});
|
||||
itemReader.setResource(getInputResource("% Comment\n" + TEST_STRING));
|
||||
itemReader.setComments(new String[] { "%" });
|
||||
testRead();
|
||||
}
|
||||
|
||||
@@ -237,7 +233,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
*/
|
||||
public void testColumnNamesInHeader() throws Exception {
|
||||
final String INPUT = "name1|name2\nvalue1|value2\nvalue3|value4";
|
||||
|
||||
|
||||
itemReader = new FlatFileItemReader();
|
||||
itemReader.setResource(getInputResource(INPUT));
|
||||
itemReader.setLineTokenizer(new DelimitedLineTokenizer('|'));
|
||||
@@ -245,11 +241,11 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
itemReader.setFirstLineIsHeader(true);
|
||||
itemReader.afterPropertiesSet();
|
||||
itemReader.open(executionContext);
|
||||
|
||||
|
||||
FieldSet fs = (FieldSet) itemReader.read();
|
||||
assertEquals("value1", fs.readString("name1"));
|
||||
assertEquals("value2", fs.readString("name2"));
|
||||
|
||||
|
||||
fs = (FieldSet) itemReader.read();
|
||||
assertEquals("value3", fs.readString("name1"));
|
||||
assertEquals("value4", fs.readString("name2"));
|
||||
@@ -260,7 +256,7 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
*/
|
||||
public void testLinesToSkip() throws Exception {
|
||||
final String INPUT = "foo bar spam\none two\nthree four";
|
||||
|
||||
|
||||
itemReader = new FlatFileItemReader();
|
||||
itemReader.setResource(getInputResource(INPUT));
|
||||
itemReader.setLineTokenizer(new DelimitedLineTokenizer(' '));
|
||||
@@ -268,62 +264,66 @@ public class FlatFileItemReaderBasicTests extends TestCase {
|
||||
itemReader.setLinesToSkip(1);
|
||||
itemReader.afterPropertiesSet();
|
||||
itemReader.open(executionContext);
|
||||
|
||||
|
||||
FieldSet fs = (FieldSet) itemReader.read();
|
||||
assertEquals("one", fs.readString(0));
|
||||
assertEquals("two", fs.readString(1));
|
||||
|
||||
|
||||
fs = (FieldSet) itemReader.read();
|
||||
assertEquals("three", fs.readString(0));
|
||||
assertEquals("four", fs.readString(1));
|
||||
}
|
||||
|
||||
public void testNonExistantResource() throws Exception{
|
||||
|
||||
|
||||
public void testNonExistantResource() throws Exception {
|
||||
|
||||
Resource resource = new NonExistentResource();
|
||||
|
||||
|
||||
FlatFileItemReader testReader = new FlatFileItemReader();
|
||||
testReader.setResource(resource);
|
||||
testReader.setLineTokenizer(tokenizer);
|
||||
testReader.setFieldSetMapper(fieldSetMapper);
|
||||
testReader.setResource(resource);
|
||||
|
||||
//afterPropertiesSet should only throw an exception if the Resource is null
|
||||
|
||||
// afterPropertiesSet should only throw an exception if the Resource is null
|
||||
testReader.afterPropertiesSet();
|
||||
|
||||
try{
|
||||
|
||||
try {
|
||||
testReader.open(executionContext);
|
||||
fail();
|
||||
}catch(IllegalStateException ex){
|
||||
//expected
|
||||
} catch (IllegalStateException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void testRuntimeFileCreation() throws Exception{
|
||||
|
||||
|
||||
public void testRuntimeFileCreation() throws Exception {
|
||||
|
||||
Resource resource = new NonExistentResource();
|
||||
|
||||
|
||||
FlatFileItemReader testReader = new FlatFileItemReader();
|
||||
testReader.setResource(resource);
|
||||
testReader.setLineTokenizer(tokenizer);
|
||||
testReader.setFieldSetMapper(fieldSetMapper);
|
||||
testReader.setResource(resource);
|
||||
|
||||
//afterPropertiesSet should only throw an exception if the Resource is null
|
||||
|
||||
// afterPropertiesSet should only throw an exception if the Resource is null
|
||||
testReader.afterPropertiesSet();
|
||||
|
||||
//replace the resource to simulate runtime resource creation
|
||||
|
||||
// replace the resource to simulate runtime resource creation
|
||||
testReader.setResource(getInputResource(TEST_STRING));
|
||||
testReader.open(executionContext);
|
||||
assertEquals(TEST_OUTPUT, testReader.read().toString());
|
||||
}
|
||||
|
||||
private class NonExistentResource extends AbstractResource{
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
|
||||
private class NonExistentResource extends AbstractResource {
|
||||
|
||||
public NonExistentResource() {
|
||||
}
|
||||
|
||||
|
||||
public boolean exists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ import org.springframework.batch.item.file.mapping.FieldSetCreator;
|
||||
import org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Tests of regular usage for {@link FlatFileItemWriter} Exception cases will be
|
||||
* in separate TestCase classes with different <code>setUp</code> and
|
||||
* <code>tearDown</code> methods
|
||||
* Tests of regular usage for {@link FlatFileItemWriter} Exception cases will be in separate TestCase classes with
|
||||
* different <code>setUp</code> and <code>tearDown</code> methods
|
||||
*
|
||||
* @author robert.kasanicky
|
||||
* @author Dave Syer
|
||||
@@ -53,12 +53,11 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
|
||||
// reads the output file to check the result
|
||||
private BufferedReader reader;
|
||||
|
||||
|
||||
private ExecutionContext executionContext;
|
||||
|
||||
/**
|
||||
* Create temporary output file, define mock behaviour, set dependencies and
|
||||
* initialize the object under test
|
||||
* Create temporary output file, define mock behaviour, set dependencies and initialize the object under test
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
@@ -87,9 +86,8 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a line from the output file, if the reader has not been created,
|
||||
* recreate. This method is only necessary because running the tests in a
|
||||
* UNIX environment locks the file if it's open for writing.
|
||||
* Read a line from the output file, if the reader has not been created, recreate. This method is only necessary
|
||||
* because running the tests in a UNIX environment locks the file if it's open for writing.
|
||||
*/
|
||||
private String readLine() throws IOException {
|
||||
|
||||
@@ -102,6 +100,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Regular usage of <code>write(String)</code> method
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testWriteString() throws Exception {
|
||||
@@ -115,6 +114,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Regular usage of <code>write(String)</code> method
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testWriteWithConverter() throws Exception {
|
||||
@@ -133,6 +133,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Regular usage of <code>write(String)</code> method
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testWriteWithConverterAndInfiniteLoop() throws Exception {
|
||||
@@ -151,6 +152,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Regular usage of <code>write(String)</code> method
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testWriteWithConverterAndString() throws Exception {
|
||||
@@ -167,6 +169,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Regular usage of <code>write(String[], LineDescriptor)</code> method
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testWriteRecord() throws Exception {
|
||||
@@ -245,7 +248,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
}
|
||||
|
||||
// 3 lines were written to the file after restart
|
||||
assertEquals(3, executionContext.getLong(FlatFileItemWriter.class.getSimpleName() + ".written"));
|
||||
assertEquals(3, executionContext.getLong(ClassUtils.getShortName(FlatFileItemWriter.class) + ".written"));
|
||||
|
||||
}
|
||||
|
||||
@@ -254,8 +257,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
try {
|
||||
inputSource.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -269,7 +271,7 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
inputSource.update(executionContext);
|
||||
assertNotNull(executionContext);
|
||||
assertEquals(3, executionContext.entrySet().size());
|
||||
assertEquals(0, executionContext.getLong(FlatFileItemWriter.class.getSimpleName() + ".current.count"));
|
||||
assertEquals(0, executionContext.getLong(ClassUtils.getShortName(FlatFileItemWriter.class) + ".current.count"));
|
||||
}
|
||||
|
||||
private void commit() throws Exception {
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.core.io.AbstractResource;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Tests for {@link StaxEventItemReader}.
|
||||
@@ -38,7 +39,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
private EventReaderDeserializer deserializer = new MockFragmentDeserializer();
|
||||
|
||||
private static final String FRAGMENT_ROOT_ELEMENT = "fragment";
|
||||
|
||||
|
||||
private ExecutionContext executionContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
@@ -55,8 +56,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
try {
|
||||
source.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected;
|
||||
}
|
||||
|
||||
@@ -65,8 +65,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
try {
|
||||
source.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
|
||||
@@ -75,15 +74,14 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
try {
|
||||
source.afterPropertiesSet();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regular usage scenario. ItemReader should pass XML fragments to
|
||||
* deserializer wrapped with StartDocument and EndDocument events.
|
||||
* Regular usage scenario. ItemReader should pass XML fragments to deserializer wrapped with StartDocument and
|
||||
* EndDocument events.
|
||||
*/
|
||||
public void testFragmentWrapping() throws Exception {
|
||||
source.afterPropertiesSet();
|
||||
@@ -120,7 +118,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
source.read();
|
||||
source.update(executionContext);
|
||||
System.out.println(executionContext);
|
||||
assertEquals(1, executionContext.getLong(StaxEventItemReader.class.getSimpleName() + ".read.count"));
|
||||
assertEquals(1, executionContext.getLong(ClassUtils.getShortName(StaxEventItemReader.class) + ".read.count"));
|
||||
List expectedAfterRestart = (List) source.read();
|
||||
|
||||
source = createNewInputSouce();
|
||||
@@ -130,20 +128,18 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore point must not exceed end of file, input source must not be
|
||||
* already initialised when restoring.
|
||||
* Restore point must not exceed end of file, input source must not be already initialised when restoring.
|
||||
*/
|
||||
public void testInvalidRestore() {
|
||||
ExecutionContext context = new ExecutionContext();
|
||||
context.putLong(StaxEventItemReader.class.getSimpleName() + ".read.count", 100000);
|
||||
context.putLong(ClassUtils.getShortName(StaxEventItemReader.class) + ".read.count", 100000);
|
||||
try {
|
||||
source.open(context);
|
||||
fail("Expected StreamException");
|
||||
}
|
||||
catch (ItemStreamException e) {
|
||||
} catch (ItemStreamException e) {
|
||||
// expected
|
||||
String message = e.getMessage();
|
||||
assertTrue("Wrong message: "+message, message.contains("must be before"));
|
||||
assertTrue("Wrong message: " + message, contains(message, "must be before"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +147,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
source.close(executionContext);
|
||||
source.update(executionContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skipping marked records after rollback.
|
||||
*/
|
||||
@@ -184,8 +181,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
source.setFragmentDeserializer(new ExceptionFragmentDeserializer());
|
||||
try {
|
||||
source.read();
|
||||
}
|
||||
catch (Exception expected) {
|
||||
} catch (Exception expected) {
|
||||
source.reset();
|
||||
}
|
||||
source.setFragmentDeserializer(deserializer);
|
||||
@@ -194,14 +190,13 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Statistics return the current record count. Calling read after end of
|
||||
* input does not increase the counter.
|
||||
* Statistics return the current record count. Calling read after end of input does not increase the counter.
|
||||
*/
|
||||
public void testExecutionContext() {
|
||||
final int NUMBER_OF_RECORDS = 2;
|
||||
source.open(executionContext);
|
||||
source.update(executionContext);
|
||||
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_RECORDS; i++) {
|
||||
long recordCount = extractRecordCount();
|
||||
assertEquals(i, recordCount);
|
||||
@@ -215,7 +210,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
}
|
||||
|
||||
private long extractRecordCount() {
|
||||
return executionContext.getLong(StaxEventItemReader.class.getSimpleName() + ".read.count");
|
||||
return executionContext.getLong(ClassUtils.getShortName(StaxEventItemReader.class) + ".read.count");
|
||||
}
|
||||
|
||||
public void testCloseWithoutOpen() throws Exception {
|
||||
@@ -243,8 +238,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
try {
|
||||
item = newSource.read();
|
||||
fail("Expected ReaderNotOpenException");
|
||||
}
|
||||
catch (ReaderNotOpenException e) {
|
||||
} catch (ReaderNotOpenException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -267,8 +261,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
|
||||
try {
|
||||
source.open(executionContext);
|
||||
}
|
||||
catch (DataAccessResourceFailureException ex) {
|
||||
} catch (DataAccessResourceFailureException ex) {
|
||||
assertTrue(ex.getCause() instanceof IOException);
|
||||
}
|
||||
|
||||
@@ -282,8 +275,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
try {
|
||||
source.open(executionContext);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
} catch (IllegalStateException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
@@ -312,15 +304,14 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple XMLEvent deserializer mock - check for the start and end
|
||||
* document events for the fragment root & end tags + skips the fragment
|
||||
* contents.
|
||||
* A simple XMLEvent deserializer mock - check for the start and end document events for the fragment root & end
|
||||
* tags + skips the fragment contents.
|
||||
*/
|
||||
private static class MockFragmentDeserializer implements EventReaderDeserializer {
|
||||
|
||||
/**
|
||||
* A simple mapFragment implementation checking the
|
||||
* StaxEventReaderItemReader basic read functionality.
|
||||
* A simple mapFragment implementation checking the StaxEventReaderItemReader basic read functionality.
|
||||
*
|
||||
* @param eventReader
|
||||
* @return list of the events from fragment body
|
||||
*/
|
||||
@@ -348,8 +339,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
XMLEvent event4 = eventReader.nextEvent();
|
||||
assertTrue(event4.isEndDocument());
|
||||
|
||||
}
|
||||
catch (XMLStreamException e) {
|
||||
} catch (XMLStreamException e) {
|
||||
throw new RuntimeException("Error occured in FragmentDeserializer", e);
|
||||
}
|
||||
return fragmentContent;
|
||||
@@ -364,7 +354,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
do {
|
||||
eventInsideFragment = eventReader.peek();
|
||||
if (eventInsideFragment instanceof EndElement
|
||||
&& ((EndElement) eventInsideFragment).getName().getLocalPart().equals(FRAGMENT_ROOT_ELEMENT)) {
|
||||
&& ((EndElement) eventInsideFragment).getName().getLocalPart().equals(FRAGMENT_ROOT_ELEMENT)) {
|
||||
break;
|
||||
}
|
||||
events.add(eventReader.nextEvent());
|
||||
@@ -375,6 +365,10 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves cursor inside the fragment body and causes rollback.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.springframework.core.io.Resource;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.XmlMappingException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.xml.transform.StaxResult;
|
||||
|
||||
/**
|
||||
@@ -30,7 +31,7 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
|
||||
// output file
|
||||
private Resource resource;
|
||||
|
||||
|
||||
private ExecutionContext executionContext;
|
||||
|
||||
// test item for writing to output
|
||||
@@ -40,7 +41,7 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
}
|
||||
};
|
||||
|
||||
private static final String TEST_STRING = StaxEventItemWriter.class.getSimpleName() + "-testString";
|
||||
private static final String TEST_STRING = ClassUtils.getShortName(StaxEventItemWriter.class) + "-testString";
|
||||
|
||||
private static final int NOT_FOUND = -1;
|
||||
|
||||
@@ -62,20 +63,20 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
// see asserts in the marshaller
|
||||
writer.write(item);
|
||||
assertFalse(marshaller.wasCalled);
|
||||
|
||||
|
||||
writer.flush();
|
||||
assertTrue(marshaller.wasCalled);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testClear() throws Exception {
|
||||
writer.open(executionContext);
|
||||
writer.write(item);
|
||||
writer.write(item);
|
||||
writer.clear();
|
||||
//writer.write(item);
|
||||
// writer.write(item);
|
||||
writer.flush();
|
||||
assertFalse(outputFileContent().contains(TEST_STRING));
|
||||
assertFalse(contains(outputFileContent(), TEST_STRING));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +98,7 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
writer.write(item);
|
||||
assertEquals("", outputFileContent());
|
||||
writer.flush();
|
||||
assertTrue(outputFileContent().contains(TEST_STRING));
|
||||
assertTrue(contains(outputFileContent(), TEST_STRING));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +117,7 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
writer.open(executionContext);
|
||||
writer.write(item);
|
||||
writer.close(executionContext);
|
||||
|
||||
|
||||
// check the output is concatenation of 'before restart' and 'after
|
||||
// restart' writes.
|
||||
String outputFile = outputFileContent();
|
||||
@@ -139,7 +140,8 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
for (int i = 1; i <= NUMBER_OF_RECORDS; i++) {
|
||||
writer.write(item);
|
||||
writer.update(executionContext);
|
||||
long writeStatistics = executionContext.getLong(StaxEventItemWriter.class.getSimpleName() + ".record.count");
|
||||
long writeStatistics = executionContext.getLong(ClassUtils.getShortName(StaxEventItemWriter.class)
|
||||
+ ".record.count");
|
||||
|
||||
assertEquals(i, writeStatistics);
|
||||
}
|
||||
@@ -168,9 +170,9 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
* Checks the received parameters.
|
||||
*/
|
||||
private class InputCheckMarshaller implements Marshaller {
|
||||
|
||||
|
||||
boolean wasCalled = false;
|
||||
|
||||
|
||||
public void marshal(Object graph, Result result) {
|
||||
wasCalled = true;
|
||||
assertTrue(result instanceof StaxResult);
|
||||
@@ -192,8 +194,7 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
StaxResult staxResult = (StaxResult) result;
|
||||
try {
|
||||
staxResult.getXMLEventWriter().add(XMLEventFactory.newInstance().createComment(graph.toString()));
|
||||
}
|
||||
catch (XMLStreamException e) {
|
||||
} catch (XMLStreamException e) {
|
||||
throw new RuntimeException("Exception while writing to output file", e);
|
||||
}
|
||||
}
|
||||
@@ -228,7 +229,11 @@ public class StaxEventItemWriterTests extends TestCase {
|
||||
source.setSaveState(true);
|
||||
|
||||
source.afterPropertiesSet();
|
||||
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
private boolean contains(String str, String searchStr) {
|
||||
return str.indexOf(searchStr) != -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@ public class LogOrRethrowExceptionHandlerTests extends TestCase {
|
||||
fail("Expected IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
assertTrue(e.getMessage().toLowerCase().indexOf("unclassified")>=0);
|
||||
assertEquals("Foo", e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class DatasourceTests extends AbstractTransactionalDataSourceSpringContex
|
||||
int count = jdbcTemplate.queryForInt("select count(*) from T_FOOS");
|
||||
assertEquals(0, count);
|
||||
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] { Integer.valueOf(0),
|
||||
"foo" });
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] { new Integer(0),
|
||||
"foo" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,19 +58,19 @@ public abstract class AbstractStaxEventReaderItemReaderTests extends TestCase {
|
||||
Trade trade1 = (Trade) results.get(0);
|
||||
assertEquals("XYZ0001", trade1.getIsin());
|
||||
assertEquals(5, trade1.getQuantity());
|
||||
assertEquals(BigDecimal.valueOf(11.39), trade1.getPrice());
|
||||
assertEquals(new BigDecimal("11.39"), trade1.getPrice());
|
||||
assertEquals("Customer1", trade1.getCustomer());
|
||||
|
||||
Trade trade2 = (Trade) results.get(1);
|
||||
assertEquals("XYZ0002", trade2.getIsin());
|
||||
assertEquals(2, trade2.getQuantity());
|
||||
assertEquals(BigDecimal.valueOf(72.99), trade2.getPrice());
|
||||
assertEquals(new BigDecimal("72.99"), trade2.getPrice());
|
||||
assertEquals("Customer2", trade2.getCustomer());
|
||||
|
||||
Trade trade3 = (Trade) results.get(2);
|
||||
assertEquals("XYZ0003", trade3.getIsin());
|
||||
assertEquals(9, trade3.getQuantity());
|
||||
assertEquals(BigDecimal.valueOf(99.99), trade3.getPrice());
|
||||
assertEquals(new BigDecimal("99.99"), trade3.getPrice());
|
||||
assertEquals("Customer3", trade3.getCustomer());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public abstract class AbstractStaxEventWriterItemWriterTests extends TestCase {
|
||||
|
||||
@@ -30,12 +31,13 @@ public abstract class AbstractStaxEventWriterItemWriterTests extends TestCase {
|
||||
|
||||
protected Resource expected = new ClassPathResource("expected-output.xml", getClass());
|
||||
|
||||
|
||||
protected List objects = new ArrayList() {{
|
||||
add(new Trade("isin1", 1, new BigDecimal(1.0), "customer1"));
|
||||
add(new Trade("isin2", 2, new BigDecimal(2.0), "customer2"));
|
||||
add(new Trade("isin3", 3, new BigDecimal(3.0), "customer3"));
|
||||
}};
|
||||
protected List objects = new ArrayList() {
|
||||
{
|
||||
add(new Trade("isin1", 1, new BigDecimal(1.0), "customer1"));
|
||||
add(new Trade("isin2", 2, new BigDecimal(2.0), "customer2"));
|
||||
add(new Trade("isin3", 3, new BigDecimal(3.0), "customer3"));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Write list of domain objects and check the output file.
|
||||
@@ -50,16 +52,15 @@ public abstract class AbstractStaxEventWriterItemWriterTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
//File outputFile = File.createTempFile("AbstractStaxStreamWriterOutputSourceTests", "xml");
|
||||
outputFile = File.createTempFile(this.getClass().getSimpleName(), ".xml");
|
||||
// File outputFile = File.createTempFile("AbstractStaxStreamWriterOutputSourceTests", "xml");
|
||||
outputFile = File.createTempFile(ClassUtils.getShortName(this.getClass()), ".xml");
|
||||
resource = new FileSystemResource(outputFile);
|
||||
writer.setResource(resource);
|
||||
|
||||
MarshallingEventWriterSerializer mapper = new MarshallingEventWriterSerializer(getMarshaller());
|
||||
writer.setSerializer(mapper);
|
||||
|
||||
|
||||
writer.open(new ExecutionContext());
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ public class ExternalRetryInBatchTests extends AbstractDependencyInjectionSpring
|
||||
// back. When it comes back for recovery this code is not
|
||||
// executed...
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
});
|
||||
@@ -145,24 +145,20 @@ public class ExternalRetryInBatchTests extends AbstractDependencyInjectionSpring
|
||||
});
|
||||
return null;
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
|
||||
if (i == 0 || i == 2) {
|
||||
assertEquals("Rollback!", e.getMessage());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
System.err.println(i + ": " + recovered);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class AsynchronousTests extends AbstractDependencyInjectionSpringContextT
|
||||
list.add(message.toString());
|
||||
String text = ((TextMessage) message).getText();
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
return new ExitStatus(text != null);
|
||||
}
|
||||
});
|
||||
@@ -116,7 +116,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
return new ExitStatus(text != null);
|
||||
}
|
||||
});
|
||||
@@ -146,7 +146,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
// The JmsTemplate is used elsewhere outside a transaction, so
|
||||
// we need to use one here that is transaction aware.
|
||||
final JmsTemplate jmsTemplate = new JmsTemplate((ConnectionFactory) applicationContext
|
||||
.getBean("txAwareConnectionFactory"));
|
||||
.getBean("txAwareConnectionFactory"));
|
||||
jmsTemplate.setReceiveTimeout(100L);
|
||||
jmsTemplate.setSessionTransacted(true);
|
||||
|
||||
@@ -156,7 +156,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
return new ExitStatus(text != null);
|
||||
}
|
||||
});
|
||||
@@ -170,11 +170,9 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
try {
|
||||
assertTrue("Not a SessionProxy - wrong spring version?", session instanceof SessionProxy);
|
||||
((SessionProxy) session).getTargetSession().rollback();
|
||||
}
|
||||
catch (JMSException e) {
|
||||
} catch (JMSException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
// swallow it
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -94,8 +94,7 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
private List recovered = new ArrayList();
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt but must receive
|
||||
* the message again.
|
||||
* Message processing is successful on the second attempt but must receive the message again.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -108,7 +107,7 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
final ItemReaderRetryCallback callback = new ItemReaderRetryCallback(provider, new AbstractItemWriter() {
|
||||
public void write(final Object text) {
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -121,15 +120,13 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
try {
|
||||
return retryTemplate.execute(callback);
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
fail("Expected Exception");
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
|
||||
assertEquals("Rollback!", e.getMessage());
|
||||
|
||||
@@ -142,8 +139,7 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
try {
|
||||
return retryTemplate.execute(callback);
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
@@ -173,7 +169,7 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
final ItemReaderRetryCallback callback = new ItemReaderRetryCallback(provider, new AbstractItemWriter() {
|
||||
public void write(final Object text) {
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
});
|
||||
@@ -186,14 +182,12 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
try {
|
||||
return retryTemplate.execute(callback);
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
|
||||
if (i < 3)
|
||||
assertEquals("Rollback!", e.getMessage());
|
||||
@@ -231,9 +225,9 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
|
||||
}
|
||||
return msgs;
|
||||
}
|
||||
|
||||
|
||||
private abstract class ItemReaderRecoverer extends AbstractItemReader implements ItemRecoverer {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,8 +73,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
List list = new ArrayList();
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt without having to
|
||||
* receive the message again.
|
||||
* Message processing is successful on the second attempt without having to receive the message again.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -83,11 +82,9 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
assertInitialState();
|
||||
|
||||
/*
|
||||
* We either want the JMS receive to be outside a transaction, or we
|
||||
* need the database transaction in the retry to be PROPAGATION_NESTED.
|
||||
* Otherwise JMS will roll back when the retry callback is eventually
|
||||
* successful because of the previous exception.
|
||||
* PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* We either want the JMS receive to be outside a transaction, or we need the database transaction in the retry
|
||||
* to be PROPAGATION_NESTED. Otherwise JMS will roll back when the retry callback is eventually successful
|
||||
* because of the previous exception. PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* transaction to fail and rollback the inner one.
|
||||
*/
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
@@ -104,7 +101,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -133,8 +130,8 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
}
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt without having to
|
||||
* receive the message again - uses JmsItemProvider internally.
|
||||
* Message processing is successful on the second attempt without having to receive the message again - uses
|
||||
* JmsItemProvider internally.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -158,7 +155,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -188,8 +185,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
}
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt without having to
|
||||
* receive the message again.
|
||||
* Message processing is successful on the second attempt without having to receive the message again.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -198,11 +194,9 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
assertInitialState();
|
||||
|
||||
/*
|
||||
* We either want the JMS receive to be outside a transaction, or we
|
||||
* need the database transaction in the retry to be PROPAGATION_NESTED.
|
||||
* Otherwise JMS will roll back when the retry callback is eventually
|
||||
* successful because of the previous exception.
|
||||
* PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* We either want the JMS receive to be outside a transaction, or we need the database transaction in the retry
|
||||
* to be PROPAGATION_NESTED. Otherwise JMS will roll back when the retry callback is eventually successful
|
||||
* because of the previous exception. PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* transaction to fail and rollback the inner one.
|
||||
*/
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
@@ -218,7 +212,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
return text;
|
||||
|
||||
}
|
||||
@@ -247,8 +241,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
}
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt but must receive
|
||||
* the message again.
|
||||
* Message processing is successful on the second attempt but must receive the message again.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -273,7 +266,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -325,7 +318,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)",
|
||||
new Object[] { Integer.valueOf(list.size()), text });
|
||||
new Object[] { new Integer(list.size()), text });
|
||||
throw new RuntimeException("Rollback!");
|
||||
|
||||
}
|
||||
@@ -335,13 +328,12 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
});
|
||||
|
||||
/*
|
||||
* N.B. the message can be re-directed to an error queue by setting
|
||||
* an error destination in a JmsItemProvider.
|
||||
* N.B. the message can be re-directed to an error queue by setting an error destination in a
|
||||
* JmsItemProvider.
|
||||
*/
|
||||
fail("Expected RuntimeException");
|
||||
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("Rollback!", e.getMessage());
|
||||
// expected
|
||||
}
|
||||
|
||||
@@ -70,8 +70,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
List list = new ArrayList();
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt without having to
|
||||
* receive the message again.
|
||||
* Message processing is successful on the second attempt without having to receive the message again.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -80,11 +79,9 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
assertInitialState();
|
||||
|
||||
/*
|
||||
* We either want the JMS receive to be outside a transaction, or we
|
||||
* need the database transaction in the retry to be PROPAGATION_NESTED.
|
||||
* Otherwise JMS will roll back when the retry callback is eventually
|
||||
* successful because of the previous exception.
|
||||
* PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* We either want the JMS receive to be outside a transaction, or we need the database transaction in the retry
|
||||
* to be PROPAGATION_NESTED. Otherwise JMS will roll back when the retry callback is eventually successful
|
||||
* because of the previous exception. PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* transaction to fail and rollback the inner one.
|
||||
*/
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
@@ -100,7 +97,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -129,8 +126,8 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
}
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt without having to
|
||||
* receive the message again - uses JmsItemProvider internally.
|
||||
* Message processing is successful on the second attempt without having to receive the message again - uses
|
||||
* JmsItemProvider internally.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -154,7 +151,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -184,8 +181,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
}
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt without having to
|
||||
* receive the message again.
|
||||
* Message processing is successful on the second attempt without having to receive the message again.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -194,11 +190,9 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
assertInitialState();
|
||||
|
||||
/*
|
||||
* We either want the JMS receive to be outside a transaction, or we
|
||||
* need the database transaction in the retry to be PROPAGATION_NESTED.
|
||||
* Otherwise JMS will roll back when the retry callback is eventually
|
||||
* successful because of the previous exception.
|
||||
* PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* We either want the JMS receive to be outside a transaction, or we need the database transaction in the retry
|
||||
* to be PROPAGATION_NESTED. Otherwise JMS will roll back when the retry callback is eventually successful
|
||||
* because of the previous exception. PROPAGATION_REQUIRES_NEW is wrong because it doesn't allow the outer
|
||||
* transaction to fail and rollback the inner one.
|
||||
*/
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
@@ -214,7 +208,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
list.add(text);
|
||||
System.err.println("Inserting: [" + list.size() + "," + text + "]");
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
return text;
|
||||
|
||||
}
|
||||
@@ -243,8 +237,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
}
|
||||
|
||||
/**
|
||||
* Message processing is successful on the second attempt but must receive
|
||||
* the message again.
|
||||
* Message processing is successful on the second attempt but must receive the message again.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@@ -269,7 +262,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", new Object[] {
|
||||
Integer.valueOf(list.size()), text });
|
||||
new Integer(list.size()), text });
|
||||
if (list.size() == 1) {
|
||||
throw new RuntimeException("Rollback!");
|
||||
}
|
||||
@@ -321,7 +314,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
final String text = (String) jmsTemplate.receiveAndConvert("queue");
|
||||
list.add(text);
|
||||
jdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)",
|
||||
new Object[] { Integer.valueOf(list.size()), text });
|
||||
new Object[] { new Integer(list.size()), text });
|
||||
throw new RuntimeException("Rollback!");
|
||||
|
||||
}
|
||||
@@ -332,8 +325,7 @@ public class SynchronousTests extends AbstractTransactionalDataSourceSpringConte
|
||||
|
||||
fail("Expected RuntimeException");
|
||||
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("Rollback!", e.getMessage());
|
||||
// expected
|
||||
}
|
||||
|
||||
@@ -203,8 +203,14 @@
|
||||
<dependency>
|
||||
<groupId>mx4j</groupId>
|
||||
<artifactId>mx4j</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<scope>optional</scope>
|
||||
<version>3.0.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<version>2.8.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.springframework.batch.sample.domain.CustomerCredit;
|
||||
*/
|
||||
public class CustomerCreditIncreaseWriter extends AbstractItemWriter {
|
||||
|
||||
public static final BigDecimal FIXED_AMOUNT = new BigDecimal(1000);
|
||||
public static final BigDecimal FIXED_AMOUNT = new BigDecimal("1000");
|
||||
|
||||
private CustomerCreditDao customerCreditDao;
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ import org.springframework.batch.sample.domain.LineItem;
|
||||
|
||||
public class OrderItemFieldSetMapperTests extends AbstractFieldSetMapperTests{
|
||||
|
||||
private static final BigDecimal DISCOUNT_AMOUNT = new BigDecimal(1);
|
||||
private static final BigDecimal DISCOUNT_PERC = new BigDecimal(2);
|
||||
private static final BigDecimal HANDLING_PRICE = new BigDecimal(3);
|
||||
private static final BigDecimal DISCOUNT_AMOUNT = new BigDecimal("1");
|
||||
private static final BigDecimal DISCOUNT_PERC = new BigDecimal("2");
|
||||
private static final BigDecimal HANDLING_PRICE = new BigDecimal("3");
|
||||
private static final long ITEM_ID = 4;
|
||||
private static final BigDecimal PRICE = new BigDecimal(5);
|
||||
private static final BigDecimal PRICE = new BigDecimal("5");
|
||||
private static final int QUANTITY = 6;
|
||||
private static final BigDecimal SHIPPING_PRICE = new BigDecimal(7);
|
||||
private static final BigDecimal TOTAL_PRICE = new BigDecimal(8);
|
||||
private static final BigDecimal SHIPPING_PRICE = new BigDecimal("7");
|
||||
private static final BigDecimal TOTAL_PRICE = new BigDecimal("8");
|
||||
|
||||
protected Object expectedDomainObject() {
|
||||
LineItem item = new LineItem();
|
||||
|
||||
Reference in New Issue
Block a user