OPEN - issue BATCH-116: Create XML input/output source which will work directly with StAX parser

http://opensource.atlassian.com/projects/spring/browse/BATCH-116

Added additional code coverage to infrastructure, validation to samples jobs, and integration tests for castor and xstream
This commit is contained in:
lucasward
2007-09-26 00:37:54 +00:00
parent fa35c229f2
commit d55a4d0984
8 changed files with 296 additions and 24 deletions

View File

@@ -7,16 +7,16 @@ import javax.xml.stream.events.XMLEvent;
/**
* Delegating XMLEventWriter, which ignores start and end document events,
* but passes through everything else.
*
*
* @author peter.zozom
* @author Robert Kasanicky
*/
class NoStartEndDocumentStreamWriter extends AbstractEventWriterWrapper {
public NoStartEndDocumentStreamWriter(XMLEventWriter wrappedEventWriter) {
super(wrappedEventWriter);
}
public void add(XMLEvent event) throws XMLStreamException {
if ((!event.isStartDocument()) && (!event.isEndDocument())) {
wrappedEventWriter.add(event);

View File

@@ -86,22 +86,21 @@ public class StaxEventReaderInputSource implements InputSource, Skippable, Resta
return item;
}
// TODO make sure exception stack is not lost in any case.
public void close() {
initialized = false;
try {
initialized = false;
fragmentReader.close();
inputStream.close();
}
catch (XMLStreamException e) {
throw new DataAccessResourceFailureException("Error while closing event reader", e);
}
catch (IOException e) {
throw new DataAccessResourceFailureException("Error while closing input stream", e);
}
finally {
try {
inputStream.close();
}
catch (IOException e) {
throw new DataAccessResourceFailureException("Error while closing input stream", e);
}
fragmentReader = null;
inputStream = null;
}
}

View File

@@ -251,17 +251,11 @@ public class StaxEventWriterOutputSource implements OutputSource, Restartable,
registerSynchronization();
File file;
FileOutputStream os = null;
try {
file = resource.getFile();
FileUtils.setUpOutputFile(file, restarted, overwriteOutput);
} catch (IOException ioe) {
throw new DataAccessResourceFailureException(
"Unable to write to file resource: [" + resource + "]", ioe);
}
FileOutputStream os = null;
try {
os = new FileOutputStream(file, true);
channel = os.getChannel();
setPosition(position);

View File

@@ -0,0 +1,134 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.io.stax;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import org.easymock.MockControl;
import com.bea.xml.stream.events.StartDocumentEvent;
import junit.framework.TestCase;
/**
* @author Lucas Ward
*
*/
public class AbstractEventReaderWrapperTests extends TestCase {
AbstractEventReaderWrapper eventReaderWrapper;
MockControl mockEventReaderControl = MockControl.createControl(XMLEventReader.class);
XMLEventReader xmlEventReader;
protected void setUp() throws Exception {
super.setUp();
xmlEventReader = (XMLEventReader)mockEventReaderControl.getMock();
eventReaderWrapper = new StubEventReader(xmlEventReader);
}
public void testClose() throws XMLStreamException {
xmlEventReader.close();
mockEventReaderControl.replay();
eventReaderWrapper.close();
mockEventReaderControl.verify();
}
public void testGetElementText() throws XMLStreamException {
String text = "text";
xmlEventReader.getElementText();
mockEventReaderControl.setReturnValue(text);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.getElementText(), text);
mockEventReaderControl.verify();
}
public void testGetProperty() throws IllegalArgumentException {
String text = "text";
xmlEventReader.getProperty("name");
mockEventReaderControl.setReturnValue(text);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.getProperty("name"), text);
mockEventReaderControl.verify();
}
public void testHasNext() {
xmlEventReader.hasNext();
mockEventReaderControl.setReturnValue(true);
mockEventReaderControl.replay();
assertTrue(eventReaderWrapper.hasNext());
mockEventReaderControl.verify();
}
public void testNext() {
String text = "text";
xmlEventReader.next();
mockEventReaderControl.setReturnValue(text);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.next(), text);
mockEventReaderControl.verify();
}
public void testNextEvent() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventReader.nextEvent();
mockEventReaderControl.setReturnValue(event);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.nextEvent(), event);
mockEventReaderControl.verify();
}
public void testNextTag() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventReader.nextTag();
mockEventReaderControl.setReturnValue(event);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.nextTag(), event);
mockEventReaderControl.verify();
}
public void testPeek() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventReader.peek();
mockEventReaderControl.setReturnValue(event);
mockEventReaderControl.replay();
assertEquals(eventReaderWrapper.peek(), event);
mockEventReaderControl.verify();
}
public void testRemove() {
xmlEventReader.remove();
mockEventReaderControl.replay();
eventReaderWrapper.remove();
mockEventReaderControl.verify();
}
private class StubEventReader extends AbstractEventReaderWrapper{
public StubEventReader(XMLEventReader wrappedEventReader) {
super(wrappedEventReader);
}
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.io.stax;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import org.easymock.MockControl;
import org.springframework.xml.stream.XmlEventStreamReader;
import com.bea.xml.stream.XMLEventReaderBase;
import com.bea.xml.stream.events.StartDocumentEvent;
import com.bea.xml.stream.util.NamespaceContextImpl;
import junit.framework.TestCase;
/**
* @author Lucas Ward
*
*/
public class AbstractEventWriterWrapperTests extends TestCase {
AbstractEventWriterWrapper eventWriterWrapper;
MockControl mockEventWriterControl = MockControl.createControl(XMLEventWriter.class);
XMLEventWriter xmlEventWriter;
protected void setUp() throws Exception {
super.setUp();
xmlEventWriter = (XMLEventWriter)mockEventWriterControl.getMock();
eventWriterWrapper = new StubEventWriter(xmlEventWriter);
}
public void testAdd() throws XMLStreamException {
XMLEvent event = new StartDocumentEvent();
xmlEventWriter.add(event);
mockEventWriterControl.replay();
eventWriterWrapper.add(event);
mockEventWriterControl.verify();
}
public void testAddReader() throws XMLStreamException {
MockControl readerControl = MockControl.createControl(XMLEventReader.class);
XMLEventReader reader = (XMLEventReader)readerControl.getMock();
xmlEventWriter.add(reader);
mockEventWriterControl.replay();
eventWriterWrapper.add(reader);
mockEventWriterControl.verify();
}
public void testClose() throws XMLStreamException {
xmlEventWriter.close();
mockEventWriterControl.replay();
eventWriterWrapper.close();
mockEventWriterControl.verify();
}
public void testFlush() throws XMLStreamException {
xmlEventWriter.flush();
mockEventWriterControl.replay();
eventWriterWrapper.flush();
mockEventWriterControl.verify();
}
public void testGetNamespaceContext() {
NamespaceContext context = new NamespaceContextImpl();
xmlEventWriter.getNamespaceContext();
mockEventWriterControl.setReturnValue(context);
mockEventWriterControl.replay();
assertEquals(eventWriterWrapper.getNamespaceContext(), context);
mockEventWriterControl.verify();
}
public void testGetPrefix() throws XMLStreamException {
String uri = "uri";
xmlEventWriter.getPrefix(uri);
mockEventWriterControl.setReturnValue(uri);
mockEventWriterControl.replay();
assertEquals(eventWriterWrapper.getPrefix(uri), uri);
mockEventWriterControl.verify();
}
public void testSetDefaultNamespace() throws XMLStreamException {
String uri = "uri";
xmlEventWriter.setDefaultNamespace(uri);
mockEventWriterControl.replay();
eventWriterWrapper.setDefaultNamespace(uri);
mockEventWriterControl.verify();
}
public void testSetNamespaceContext()
throws XMLStreamException {
NamespaceContext context = new NamespaceContextImpl();
xmlEventWriter.setNamespaceContext(context);
mockEventWriterControl.replay();
eventWriterWrapper.setNamespaceContext(context);
mockEventWriterControl.verify();
}
public void testSetPrefix() throws XMLStreamException {
String uri = "uri";
String prefix = "prefix";
xmlEventWriter.setPrefix(prefix, uri);
mockEventWriterControl.replay();
eventWriterWrapper.setPrefix(prefix, uri);
mockEventWriterControl.verify();
}
private class StubEventWriter extends AbstractEventWriterWrapper{
public StubEventWriter(XMLEventWriter wrappedEventWriter) {
super(wrappedEventWriter);
}
}
}

View File

@@ -47,7 +47,8 @@ public class DefaultFragmentEventReaderTests extends TestCase {
* peek() has no side effects on the inner state of reader.
*/
public void testFragmentWrapping() throws XMLStreamException {
assertTrue(fragmentReader.hasNext());
moveCursorToNextElementEvent(); // move to root start
fragmentReader.nextEvent(); // skip root
moveCursorToNextElementEvent(); // move to fragment start
@@ -75,6 +76,7 @@ public class DefaultFragmentEventReaderTests extends TestCase {
// now the reader should behave like the document has finished
assertTrue(fragmentReader.peek() == null);
assertFalse(fragmentReader.hasNext());
try{
fragmentReader.nextEvent();
@@ -107,6 +109,7 @@ public class DefaultFragmentEventReaderTests extends TestCase {
XMLEvent misc2 = fragmentReader.nextEvent();
assertTrue(EventHelper.startElementName(misc2).equals("misc2"));
}
private void moveCursorToNextElementEvent() throws XMLStreamException {
XMLEvent event = eventReader.peek();

View File

@@ -1,9 +1,7 @@
package org.springframework.batch.io.stax;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

View File

@@ -97,7 +97,7 @@ public class StaxEventWriterOutputSourceTests extends TestCase {
source = newOutputSource();
source.restoreFrom(restartData);
source.write(record);
source.close();
source.destroy();
// check the output is concatenation of 'before restart' and 'after restart' writes.
String outputFile = outputFileContent();
@@ -187,13 +187,20 @@ public class StaxEventWriterOutputSourceTests extends TestCase {
/**
* @return new instance of fully configured output source
*/
private StaxEventWriterOutputSource newOutputSource() {
private StaxEventWriterOutputSource newOutputSource() throws Exception {
StaxEventWriterOutputSource source = new StaxEventWriterOutputSource();
source.setResource(resource);
Marshaller marshaller = new SimpleMarshaller();
MarshallingObjectToXmlSerializer serializer = new MarshallingObjectToXmlSerializer(marshaller);
source.setSerializer(serializer);
source.setEncoding("UTF-8");
source.setRootTagName("root");
source.setVersion("1.0");
source.setOverwriteOutput(true);
source.afterPropertiesSet();
return source;
}