diff --git a/infrastructure/src/main/java/org/springframework/batch/io/stax/NoStartEndDocumentStreamWriter.java b/infrastructure/src/main/java/org/springframework/batch/io/stax/NoStartEndDocumentStreamWriter.java index cea4cd6d0..7b5bb6dae 100644 --- a/infrastructure/src/main/java/org/springframework/batch/io/stax/NoStartEndDocumentStreamWriter.java +++ b/infrastructure/src/main/java/org/springframework/batch/io/stax/NoStartEndDocumentStreamWriter.java @@ -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); diff --git a/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventReaderInputSource.java b/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventReaderInputSource.java index 9aa8f7af7..6e00e46d2 100644 --- a/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventReaderInputSource.java +++ b/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventReaderInputSource.java @@ -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; } } diff --git a/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventWriterOutputSource.java b/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventWriterOutputSource.java index 79deb14ed..b1b56bcff 100644 --- a/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventWriterOutputSource.java +++ b/infrastructure/src/main/java/org/springframework/batch/io/stax/StaxEventWriterOutputSource.java @@ -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); diff --git a/infrastructure/src/test/java/org/springframework/batch/io/stax/AbstractEventReaderWrapperTests.java b/infrastructure/src/test/java/org/springframework/batch/io/stax/AbstractEventReaderWrapperTests.java new file mode 100644 index 000000000..fcd0bf9db --- /dev/null +++ b/infrastructure/src/test/java/org/springframework/batch/io/stax/AbstractEventReaderWrapperTests.java @@ -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); + } + } +} diff --git a/infrastructure/src/test/java/org/springframework/batch/io/stax/AbstractEventWriterWrapperTests.java b/infrastructure/src/test/java/org/springframework/batch/io/stax/AbstractEventWriterWrapperTests.java new file mode 100644 index 000000000..961b51601 --- /dev/null +++ b/infrastructure/src/test/java/org/springframework/batch/io/stax/AbstractEventWriterWrapperTests.java @@ -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); + } + } +} diff --git a/infrastructure/src/test/java/org/springframework/batch/io/stax/DefaultFragmentEventReaderTests.java b/infrastructure/src/test/java/org/springframework/batch/io/stax/DefaultFragmentEventReaderTests.java index 5438fb98a..ae0212588 100644 --- a/infrastructure/src/test/java/org/springframework/batch/io/stax/DefaultFragmentEventReaderTests.java +++ b/infrastructure/src/test/java/org/springframework/batch/io/stax/DefaultFragmentEventReaderTests.java @@ -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(); diff --git a/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventReaderInputSourceTests.java b/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventReaderInputSourceTests.java index f6c32a399..0f8fd1d9a 100644 --- a/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventReaderInputSourceTests.java +++ b/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventReaderInputSourceTests.java @@ -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; diff --git a/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventWriterOutputSourceTests.java b/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventWriterOutputSourceTests.java index 529adb878..e973d5405 100644 --- a/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventWriterOutputSourceTests.java +++ b/infrastructure/src/test/java/org/springframework/batch/io/stax/StaxEventWriterOutputSourceTests.java @@ -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; }