IN PROGRESS - BATCH-827: Create Sample job for reading and writing headers and footers
This commit is contained in:
@@ -247,8 +247,8 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
|
||||
if (outputState.lastMarkedByteOffsetPosition == 0) {
|
||||
if (headerCallback != null) {
|
||||
try {
|
||||
headerCallback.write(state.outputBufferedWriter);
|
||||
state.write("\n");
|
||||
headerCallback.write(outputState.outputBufferedWriter);
|
||||
outputState.write("\n");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new FlushFailedException("Could not write headers. The file may be corrupt.", e);
|
||||
@@ -422,6 +422,7 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
|
||||
|
||||
outputBufferedWriter = getBufferedWriter(fileChannel, encoding);
|
||||
|
||||
Assert.state(outputBufferedWriter != null);
|
||||
// in case of restarting reset position to last committed point
|
||||
if (restarted) {
|
||||
checkFileSize();
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#Mon Aug 11 02:58:58 EDT 2008
|
||||
#Thu Sep 11 14:26:57 CEST 2008
|
||||
eclipse.preferences.version=1
|
||||
org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true
|
||||
org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=true
|
||||
org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=false
|
||||
org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=true
|
||||
org.springframework.ide.eclipse.core.enable.project.preferences=false
|
||||
org.springframework.ide.eclipse.core.validator.enable.com.springsource.platform.ide.manifest.core.manifestvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.ap.quickfix.manifestvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false
|
||||
org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.applicationSymbolicNameRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.applicationVersionRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true
|
||||
@@ -45,8 +45,8 @@ org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.i
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true
|
||||
org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.1.0.v200806081427]]></pluginVersion>
|
||||
<pluginVersion><![CDATA[2.0.6.v200806241357]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
@@ -41,6 +41,7 @@
|
||||
<config>src/main/resources/staging-test-context.xml</config>
|
||||
<config>src/main/resources/org/springframework/batch/sample/config/common-context.xml</config>
|
||||
<config>src/main/resources/jobs/taskletJob.xml</config>
|
||||
<config>src/main/resources/jobs/headerFooterSample.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
<configSet>
|
||||
@@ -215,17 +216,6 @@
|
||||
<config>src/main/resources/org/springframework/batch/sample/config/common-context.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
<configSet>
|
||||
<name><![CDATA[jmxLauncher]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
<config>src/main/resources/adhoc-job-launcher-context.xml</config>
|
||||
<config>src/main/resources/data-source-context.xml</config>
|
||||
<config>src/main/resources/simple-job-launcher-context.xml</config>
|
||||
<config>src/main/resources/org/springframework/batch/sample/config/common-context.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
<configSet>
|
||||
<name><![CDATA[skipSample]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
@@ -345,5 +335,27 @@
|
||||
<config>src/main/resources/jobs/taskletJob.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
<configSet>
|
||||
<name><![CDATA[jmxLauncher]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
<config>src/main/resources/adhoc-job-launcher-context.xml</config>
|
||||
<config>src/main/resources/data-source-context.xml</config>
|
||||
<config>src/main/resources/simple-job-launcher-context.xml</config>
|
||||
<config>src/main/resources/org/springframework/batch/sample/config/common-context.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
<configSet>
|
||||
<name><![CDATA[headerFooter]]></name>
|
||||
<allowBeanDefinitionOverriding>true</allowBeanDefinitionOverriding>
|
||||
<incomplete>false</incomplete>
|
||||
<configs>
|
||||
<config>src/main/resources/data-source-context.xml</config>
|
||||
<config>src/main/resources/jobs/headerFooterSample.xml</config>
|
||||
<config>src/main/resources/org/springframework/batch/sample/config/common-context.xml</config>
|
||||
<config>src/main/resources/simple-job-launcher-context.xml</config>
|
||||
</configs>
|
||||
</configSet>
|
||||
</configSets>
|
||||
</beansProjectDescription>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.batch.sample.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
|
||||
import org.springframework.batch.item.file.FileWriterCallback;
|
||||
import org.springframework.batch.item.file.FlatFileItemReader;
|
||||
import org.springframework.batch.item.file.FlatFileItemWriter;
|
||||
import org.springframework.batch.item.file.LineCallbackHandler;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Designed to be registered with both {@link FlatFileItemReader} and
|
||||
* {@link FlatFileItemWriter} and copy header line from input file to output
|
||||
* file.
|
||||
*/
|
||||
public class HeaderCopyCallback implements LineCallbackHandler, FileWriterCallback {
|
||||
|
||||
private String header = "";
|
||||
|
||||
public void handleLine(String line) {
|
||||
Assert.notNull(line);
|
||||
this.header = line;
|
||||
}
|
||||
|
||||
public void write(Writer writer) throws IOException {
|
||||
writer.write("header from input: " + header);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.springframework.batch.sample.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
|
||||
import org.springframework.batch.item.file.FileWriterCallback;
|
||||
|
||||
/**
|
||||
* Writes summary info in the footer of a file.
|
||||
*/
|
||||
public class SummaryFooterCallback extends StepExecutionListenerSupport implements FileWriterCallback{
|
||||
|
||||
private StepExecution stepExecution;
|
||||
|
||||
public void write(Writer writer) throws IOException {
|
||||
writer.write("footer - number of items written: " + stepExecution.getWriteCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeStep(StepExecution stepExecution) {
|
||||
this.stepExecution = stepExecution;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# next line is a header and should be copied to to output file
|
||||
names
|
||||
john
|
||||
joe
|
||||
jane
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
|
||||
<description>
|
||||
Showcases reading and writing of headers and footers. Copies header from input to output and adds a footer.
|
||||
</description>
|
||||
<bean id="headerFooterSample" parent="simpleJob">
|
||||
<property name="steps">
|
||||
<bean id="step1" parent="simpleStep" p:commitInterval="3">
|
||||
<property name="streams">
|
||||
<list>
|
||||
<!--
|
||||
explicit registration to enforce ordering (header needs to be
|
||||
read before it can be written)
|
||||
-->
|
||||
<ref bean="reader" />
|
||||
<ref bean="writer" />
|
||||
</list>
|
||||
</property>
|
||||
<property name="listeners" ref="footerCallback" />
|
||||
<property name="itemReader" ref="reader" />
|
||||
<property name="itemWriter" ref="writer" />
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader">
|
||||
<property name="resource" ref="inputResource" />
|
||||
<property name="lineTokenizer">
|
||||
<bean
|
||||
class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
|
||||
<property name="delimiter" value="," />
|
||||
</bean>
|
||||
</property>
|
||||
<property name="fieldSetMapper">
|
||||
<bean
|
||||
class="org.springframework.batch.item.file.mapping.PassThroughFieldSetMapper" />
|
||||
</property>
|
||||
<property name="headerCallback" ref="headerCopier" />
|
||||
<property name="firstLineIsHeader" value="true" />
|
||||
</bean>
|
||||
<bean id="writer" class="org.springframework.batch.item.file.FlatFileItemWriter">
|
||||
<property name="resource" ref="outputResource" />
|
||||
<property name="lineAggregator">
|
||||
<bean
|
||||
class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
|
||||
</property>
|
||||
<property name="headerCallback" ref="headerCopier" />
|
||||
<property name="footerCallback" ref="footerCallback" />
|
||||
</bean>
|
||||
<bean id="footerCallback" class="org.springframework.batch.sample.support.SummaryFooterCallback" />
|
||||
<bean id="headerCopier"
|
||||
class="org.springframework.batch.sample.support.HeaderCopyCallback" />
|
||||
<bean id="inputResource" class="org.springframework.core.io.ClassPathResource">
|
||||
<constructor-arg type="java.lang.String"
|
||||
value="data/headerFooterSample/input.txt" />
|
||||
</bean>
|
||||
<bean id="outputResource" class="org.springframework.core.io.FileSystemResource">
|
||||
<constructor-arg type="java.lang.String"
|
||||
value="target/test-outputs/headerFooterOutput.txt" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.springframework.batch.sample;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class HeaderFooterSampleFunctionalTests extends AbstractValidatingBatchLauncherTests {
|
||||
|
||||
@Override
|
||||
protected void validatePostConditions() throws Exception {
|
||||
Resource input = (Resource) applicationContext.getBean("inputResource", Resource.class);
|
||||
Resource output = (Resource) applicationContext.getBean("outputResource", Resource.class);
|
||||
|
||||
BufferedReader inputReader = new BufferedReader(new FileReader(input.getFile()));
|
||||
BufferedReader outputReader = new BufferedReader(new FileReader(output.getFile()));
|
||||
|
||||
// skip initial comment from input file
|
||||
inputReader.readLine();
|
||||
|
||||
String line;
|
||||
|
||||
int lineCount = 0;
|
||||
while ((line = inputReader.readLine()) != null) {
|
||||
lineCount++;
|
||||
assertTrue("input line should correspond to output line", outputReader.readLine().contains(line));
|
||||
}
|
||||
|
||||
// footer contains the item count
|
||||
int itemCount = lineCount - 1; // minus 1 due to header line
|
||||
assertTrue(outputReader.readLine().contains(String.valueOf(itemCount)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
|
||||
<import resource="classpath:/simple-job-launcher-context.xml" />
|
||||
<import resource="classpath:/jobs/headerFooterSample.xml" />
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user