IN PROGRESS - BATCH-763: Create callback for header and footer writing in xml and flat files
added footers to flatfile and stax writers
This commit is contained in:
@@ -80,6 +80,8 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
|
||||
|
||||
private List<String> headerLines = new ArrayList<String>();
|
||||
|
||||
private List<String> footerLines = new ArrayList<String>();
|
||||
|
||||
private String lineSeparator = DEFAULT_LINE_SEPARATOR;
|
||||
|
||||
public FlatFileItemWriter() {
|
||||
@@ -160,6 +162,16 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
|
||||
this.headerLines = Arrays.asList(headerLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for footer lines. These will be output at the end of the
|
||||
* file when the writer is closed.
|
||||
*
|
||||
* @param footerLines the footer lines to set
|
||||
*/
|
||||
public void setFooterLines(String[] footerLines) {
|
||||
this.footerLines = Arrays.asList(footerLines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a string followed by a "new line", where the format of the new
|
||||
* line separator is determined by the underlying operating system. If the
|
||||
@@ -190,7 +202,6 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
|
||||
throw new FlushFailedException("Could not write data. The file may be corrupt.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,8 +209,18 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
|
||||
*/
|
||||
public void close(ExecutionContext executionContext) {
|
||||
if (state != null) {
|
||||
getOutputState().close();
|
||||
state = null;
|
||||
try {
|
||||
for (String line : footerLines) {
|
||||
state.write(line + lineSeparator);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ItemStreamException("Failed to writer footer before closing", e);
|
||||
}
|
||||
finally {
|
||||
getOutputState().close();
|
||||
state = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,6 +373,7 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
|
||||
* Close the open resource and reset counters.
|
||||
*/
|
||||
public void close() {
|
||||
|
||||
initialized = false;
|
||||
restarted = false;
|
||||
try {
|
||||
|
||||
@@ -110,7 +110,9 @@ public class StaxEventItemWriter<T> extends ExecutionContextUserSupport implemen
|
||||
|
||||
private boolean saveState = true;
|
||||
|
||||
private List<?> headers = new ArrayList<Object>();
|
||||
private List<?> headerItems = new ArrayList<Object>();
|
||||
|
||||
private List<?> footerItems = new ArrayList<Object>();
|
||||
|
||||
public StaxEventItemWriter() {
|
||||
setName(ClassUtils.getShortName(StaxEventItemWriter.class));
|
||||
@@ -218,14 +220,25 @@ public class StaxEventItemWriter<T> extends ExecutionContextUserSupport implemen
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the headers. This list will be marshalled and output before
|
||||
* any calls to {@link #write(List)}. Header item type is not restricted,
|
||||
* but note the {@link #setMarshaller(Marshaller)} needs to support
|
||||
* the type.
|
||||
* @param headers
|
||||
* Setter for the headerItems. This list will be marshalled and output
|
||||
* before any calls to {@link #write(List)}. Header item type is not
|
||||
* restricted, but note the {@link #setMarshaller(Marshaller)} needs to
|
||||
* support the type.
|
||||
* @param headerItems
|
||||
*/
|
||||
public void setHeaderItems(List<?> headers) {
|
||||
this.headers = headers;
|
||||
public void setHeaderItems(List<?> headerItems) {
|
||||
this.headerItems = headerItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the footerItems. This list will be marshalled and output
|
||||
* immediately before the writer is closed. Footer item type is not
|
||||
* restricted, but note the {@link #setMarshaller(Marshaller)} needs to
|
||||
* support the type.
|
||||
* @param footerItems
|
||||
*/
|
||||
public void setFooterItems(List<?> footerItems) {
|
||||
this.footerItems = footerItems;
|
||||
}
|
||||
|
||||
public void setSaveState(boolean saveState) {
|
||||
@@ -262,10 +275,10 @@ public class StaxEventItemWriter<T> extends ExecutionContextUserSupport implemen
|
||||
|
||||
if (startAtPosition == 0) {
|
||||
try {
|
||||
doWrite(headers);
|
||||
doWrite(headerItems);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new ItemStreamException("Failed to write headers", e);
|
||||
throw new ItemStreamException("Failed to write headerItems", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,16 +396,33 @@ public class StaxEventItemWriter<T> extends ExecutionContextUserSupport implemen
|
||||
}
|
||||
|
||||
try {
|
||||
doWrite(footerItems);
|
||||
delegateEventWriter.flush();
|
||||
endDocument(delegateEventWriter);
|
||||
eventWriter.close();
|
||||
channel.close();
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
throw new DataAccessResourceFailureException("Unable to close file resource: [" + resource + "]", xse);
|
||||
catch (IOException e) {
|
||||
throw new ItemStreamException("Failed to write footer items", e);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
throw new DataAccessResourceFailureException("Unable to close file resource: [" + resource + "]", ioe);
|
||||
catch (XMLStreamException e) {
|
||||
throw new ItemStreamException("Failed to write end document tag", e);
|
||||
}
|
||||
finally {
|
||||
|
||||
try {
|
||||
eventWriter.close();
|
||||
}
|
||||
catch (XMLStreamException xse) {
|
||||
log.error("Unable to close file resource: [" + resource + "] " + xse);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
channel.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
log.error("Unable to close file resource: [" + resource + "] " + ioe);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,11 +203,13 @@ public class FlatFileItemWriterTests {
|
||||
@Test
|
||||
public void testRestart() throws Exception {
|
||||
|
||||
writer.setFooterLines(new String[] { "footer" });
|
||||
|
||||
writer.open(executionContext);
|
||||
// write some lines
|
||||
writer.write(Arrays.asList(new String[] { "testLine1", "testLine2", "testLine3" }));
|
||||
// write more lines
|
||||
writer.write(Arrays.asList(new String[] {"testLine4", "testLine5"}));
|
||||
writer.write(Arrays.asList(new String[] { "testLine4", "testLine5" }));
|
||||
// get restart data
|
||||
writer.update(executionContext);
|
||||
// close template
|
||||
@@ -216,7 +218,7 @@ public class FlatFileItemWriterTests {
|
||||
// init with correct data
|
||||
writer.open(executionContext);
|
||||
// write more lines
|
||||
writer.write(Arrays.asList(new String[] {"testLine6","testLine7","testLine8"}));
|
||||
writer.write(Arrays.asList(new String[] { "testLine6", "testLine7", "testLine8" }));
|
||||
// get statistics
|
||||
writer.update(executionContext);
|
||||
// close template
|
||||
@@ -226,6 +228,8 @@ public class FlatFileItemWriterTests {
|
||||
for (int i = 1; i <= 8; i++) {
|
||||
assertEquals("testLine" + i, readLine());
|
||||
}
|
||||
|
||||
assertEquals("footer", readLine());
|
||||
|
||||
// 3 lines were written to the file after restart
|
||||
assertEquals(3, executionContext.getLong(ClassUtils.getShortName(FlatFileItemWriter.class) + ".written"));
|
||||
@@ -303,6 +307,17 @@ public class FlatFileItemWriterTests {
|
||||
assertEquals(TEST_STRING, lineFromFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteFooter() throws Exception {
|
||||
writer.setFooterLines(new String[] { "a", "b" });
|
||||
writer.open(executionContext);
|
||||
writer.write(Collections.singletonList(TEST_STRING));
|
||||
writer.close(executionContext);
|
||||
assertEquals(TEST_STRING, readLine());
|
||||
assertEquals("a", readLine());
|
||||
assertEquals("b", readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteHeader() throws Exception {
|
||||
writer.setHeaderLines(new String[] { "a", "b" });
|
||||
|
||||
@@ -95,8 +95,9 @@ public class StaxEventItemWriterTests {
|
||||
// check the output is concatenation of 'before restart' and 'after
|
||||
// restart' writes.
|
||||
String outputFile = outputFileContent();
|
||||
|
||||
System.out.println(outputFile);
|
||||
assertEquals(2, StringUtils.countOccurrencesOf(outputFile, TEST_STRING));
|
||||
assertTrue(outputFile.contains("<root>" + TEST_STRING + TEST_STRING + "</root>"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +107,12 @@ public class StaxEventItemWriterTests {
|
||||
public void testWriteWithHeader() throws Exception {
|
||||
final Object header1 = new Object();
|
||||
final Object header2 = new Object();
|
||||
writer.setHeaderItems(new ArrayList<Object>() {{add(header1); add(header2); }});
|
||||
writer.setHeaderItems(new ArrayList<Object>() {
|
||||
{
|
||||
add(header1);
|
||||
add(header2);
|
||||
}
|
||||
});
|
||||
writer.open(executionContext);
|
||||
writer.write(items);
|
||||
String content = outputFileContent();
|
||||
|
||||
Reference in New Issue
Block a user