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 unit tests.
This commit is contained in:
@@ -8,7 +8,6 @@ import javax.xml.transform.Result;
|
|||||||
import org.springframework.batch.io.stax.ObjectToXmlSerializer;
|
import org.springframework.batch.io.stax.ObjectToXmlSerializer;
|
||||||
import org.springframework.dao.DataAccessResourceFailureException;
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
import org.springframework.oxm.Marshaller;
|
import org.springframework.oxm.Marshaller;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.xml.transform.StaxResult;
|
import org.springframework.xml.transform.StaxResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,21 +7,21 @@ import javax.xml.stream.XMLEventReader;
|
|||||||
import org.springframework.batch.io.stax.FragmentDeserializer;
|
import org.springframework.batch.io.stax.FragmentDeserializer;
|
||||||
import org.springframework.dao.DataAccessResourceFailureException;
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
import org.springframework.oxm.Unmarshaller;
|
import org.springframework.oxm.Unmarshaller;
|
||||||
import org.springframework.oxm.UnmarshallingFailureException;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.oxm.XmlMappingException;
|
|
||||||
import org.springframework.xml.transform.StaxSource;
|
import org.springframework.xml.transform.StaxSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegates deserializing to Spring-WS {@link Unmarshaller}.
|
* Delegates deserializing to Spring-WS {@link Unmarshaller}.
|
||||||
*
|
*
|
||||||
* @author Robert Kasanicky
|
* @author Robert Kasanicky
|
||||||
* @authoer Lucas Ward
|
* @author Lucas Ward
|
||||||
*/
|
*/
|
||||||
public class UnmarshallingFragmentDeserializer implements FragmentDeserializer {
|
public class UnmarshallingFragmentDeserializer implements FragmentDeserializer {
|
||||||
|
|
||||||
private Unmarshaller unmarshaller;
|
private Unmarshaller unmarshaller;
|
||||||
|
|
||||||
public UnmarshallingFragmentDeserializer(Unmarshaller unmarshaller){
|
public UnmarshallingFragmentDeserializer(Unmarshaller unmarshaller){
|
||||||
|
Assert.notNull(unmarshaller);
|
||||||
this.unmarshaller = unmarshaller;
|
this.unmarshaller = unmarshaller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,9 +30,6 @@ public class UnmarshallingFragmentDeserializer implements FragmentDeserializer {
|
|||||||
try {
|
try {
|
||||||
item = unmarshaller.unmarshal(new StaxSource(eventReader));
|
item = unmarshaller.unmarshal(new StaxSource(eventReader));
|
||||||
}
|
}
|
||||||
catch (XmlMappingException e) {
|
|
||||||
throw new UnmarshallingFailureException("Mapping failure during unmarshalling", e);
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
throw new DataAccessResourceFailureException("IO error during unmarshalling", e);
|
throw new DataAccessResourceFailureException("IO error during unmarshalling", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
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.events.XMLEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates all functionality to the wrapped writer allowing
|
||||||
|
* subclasses to override only the methods they want to change.
|
||||||
|
*
|
||||||
|
* @author Robert Kasanicky
|
||||||
|
*/
|
||||||
|
abstract class AbstractEventWriterWrapper implements XMLEventWriter {
|
||||||
|
|
||||||
|
protected XMLEventWriter wrappedEventWriter;
|
||||||
|
|
||||||
|
public AbstractEventWriterWrapper(XMLEventWriter wrappedEventWriter) {
|
||||||
|
this.wrappedEventWriter = wrappedEventWriter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(XMLEvent event) throws XMLStreamException {
|
||||||
|
wrappedEventWriter.add(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(XMLEventReader reader) throws XMLStreamException {
|
||||||
|
wrappedEventWriter.add(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws XMLStreamException {
|
||||||
|
wrappedEventWriter.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws XMLStreamException {
|
||||||
|
wrappedEventWriter.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamespaceContext getNamespaceContext() {
|
||||||
|
return wrappedEventWriter.getNamespaceContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix(String uri) throws XMLStreamException {
|
||||||
|
return wrappedEventWriter.getPrefix(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultNamespace(String uri) throws XMLStreamException {
|
||||||
|
wrappedEventWriter.setDefaultNamespace(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
|
||||||
|
wrappedEventWriter.setNamespaceContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrefix(String prefix, String uri) throws XMLStreamException {
|
||||||
|
wrappedEventWriter.setPrefix(prefix, uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package org.springframework.batch.io.stax;
|
package org.springframework.batch.io.stax;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.events.Characters;
|
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
@@ -11,27 +12,26 @@ import org.springframework.util.Assert;
|
|||||||
/**
|
/**
|
||||||
* Class used to wrap XMLEventReader. Events from wrapped reader are stored in
|
* Class used to wrap XMLEventReader. Events from wrapped reader are stored in
|
||||||
* {@link EventSequence} to support transactions.
|
* {@link EventSequence} to support transactions.
|
||||||
*
|
*
|
||||||
* @author tomas.slanina
|
* @author Tomas Slanina
|
||||||
|
* @author Robert Kasanicky
|
||||||
*/
|
*/
|
||||||
class DefaultTransactionalEventReader implements TransactionalEventReader, InitializingBean {
|
class DefaultTransactionalEventReader extends AbstractEventReaderWrapper implements TransactionalEventReader, InitializingBean {
|
||||||
|
|
||||||
private EventSequence recorder = new EventSequence();
|
private EventSequence recorder = new EventSequence();
|
||||||
|
|
||||||
private XMLEventReader parent;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates instance of this class and wraps XMLEventReader.
|
* Creates instance of this class and wraps XMLEventReader.
|
||||||
*
|
*
|
||||||
* @param parent event reader to be wrapped.
|
* @param parent event reader to be wrapped.
|
||||||
*/
|
*/
|
||||||
public DefaultTransactionalEventReader(XMLEventReader parent) {
|
public DefaultTransactionalEventReader(XMLEventReader wrappedReader) {
|
||||||
setParent(parent);
|
super(wrappedReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(parent);
|
Assert.notNull(wrappedEventReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,178 +43,54 @@ class DefaultTransactionalEventReader implements TransactionalEventReader, Initi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback on transacion commit.
|
* Callback on transacion commit.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void onCommit() {
|
public void onCommit() {
|
||||||
recorder.clear();
|
recorder.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the parent
|
|
||||||
*/
|
|
||||||
public XMLEventReader getParent() {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param parent the parent to set
|
|
||||||
*/
|
|
||||||
public void setParent(XMLEventReader parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param recorder the recorder to set
|
|
||||||
*/
|
|
||||||
public void setRecorder(EventSequence recorder) {
|
|
||||||
this.recorder = recorder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the xml event recorder
|
|
||||||
* @return the xml event recorder
|
|
||||||
*/
|
|
||||||
public EventSequence getRecorder() {
|
|
||||||
return recorder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frees any resources associated with this Reader. This method does not
|
|
||||||
* close the underlying input source.
|
|
||||||
*
|
|
||||||
* @throws XMLStreamException if there are errors freeing associated
|
|
||||||
* resources
|
|
||||||
*/
|
|
||||||
public void close() throws XMLStreamException {
|
|
||||||
parent.close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the content of a text-only element. Precondition: the current event
|
|
||||||
* is START_ELEMENT. Postcondition: The current event is the corresponding
|
|
||||||
* END_ELEMENT.
|
|
||||||
*
|
|
||||||
* @throws XMLStreamException if the current event is not a START_ELEMENT or
|
|
||||||
* if a non text element is encountered
|
|
||||||
*/
|
|
||||||
public String getElementText() throws XMLStreamException {
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
XMLEvent e = nextEvent();
|
|
||||||
if (!e.isStartElement()) {
|
|
||||||
throw new XMLStreamException(
|
|
||||||
"Precondition for readText is nextEvent().getEventType() == START_ELEMENT (got " + e.getEventType()
|
|
||||||
+ ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (hasNext()) {
|
|
||||||
e = peek();
|
|
||||||
if (e.isStartElement()) {
|
|
||||||
throw new XMLStreamException("Unexpected Element start");
|
|
||||||
}
|
|
||||||
if (e.isCharacters()) {
|
|
||||||
buf.append(((Characters) e).getData());
|
|
||||||
}
|
|
||||||
if (e.isEndElement()) {
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
nextEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new XMLStreamException("Unexpected end of Document");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of a feature/property from the underlying implementation
|
|
||||||
*
|
|
||||||
* @param name The name of the property
|
|
||||||
* @return The value of the property
|
|
||||||
* @throws IllegalArgumentException if the property is not supported
|
|
||||||
*/
|
|
||||||
public Object getProperty(String name) throws IllegalArgumentException {
|
|
||||||
return parent.getProperty(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there are more events. Returns true if there are more events and
|
* Check if there are more events. Returns true if there are more events and
|
||||||
* false otherwise.
|
* false otherwise.
|
||||||
*
|
*
|
||||||
* @return true if the event reader has more events, false otherwise
|
* @return true if the event reader has more events, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return recorder.hasNext() || parent.hasNext();
|
return recorder.hasNext() || wrappedEventReader.hasNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next XMLEvent
|
* Get the next XMLEvent
|
||||||
*
|
*
|
||||||
* @see XMLEvent
|
* @see XMLEvent
|
||||||
* @throws XMLStreamException if there is an error with the underlying XML.
|
* @throws XMLStreamException if there is an error with the underlying XML.
|
||||||
* @throws NoSuchElementException iteration has no more elements.
|
* @throws NoSuchElementException iteration has no more elements.
|
||||||
*/
|
*/
|
||||||
public XMLEvent nextEvent() throws XMLStreamException {
|
public XMLEvent nextEvent() throws XMLStreamException {
|
||||||
if (!recorder.hasNext()) {
|
if (!recorder.hasNext()) {
|
||||||
recorder.addEvent(parent.nextEvent());
|
recorder.addEvent(wrappedEventReader.nextEvent());
|
||||||
}
|
}
|
||||||
return recorder.nextEvent();
|
return recorder.nextEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Skips any insignificant space events until a START_ELEMENT or END_ELEMENT
|
|
||||||
* is reached. If anything other than space characters are encountered, an
|
|
||||||
* exception is thrown. This method should be used when processing
|
|
||||||
* element-only content because the parser is not able to recognize
|
|
||||||
* ignorable whitespace if the DTD is missing or not interpreted.
|
|
||||||
*
|
|
||||||
* @throws XMLStreamException if anything other than space characters are
|
|
||||||
* encountered
|
|
||||||
*/
|
|
||||||
public XMLEvent nextTag() throws XMLStreamException {
|
|
||||||
while (hasNext()) {
|
|
||||||
XMLEvent e = nextEvent();
|
|
||||||
if (e.isCharacters() && !((Characters) e).isWhiteSpace()) {
|
|
||||||
throw new XMLStreamException("Unexpected text");
|
|
||||||
}
|
|
||||||
if (e.isStartElement() || e.isEndElement()) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new XMLStreamException("Unexpected end of Document");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the next XMLEvent without reading it from the stream. Returns null
|
* Check the next XMLEvent without reading it from the stream. Returns null
|
||||||
* if the stream is at EOF or has no more XMLEvents. A call to peek() will
|
* if the stream is at EOF or has no more XMLEvents. A call to peek() will
|
||||||
* be equal to the next return of next().
|
* be equal to the next return of next().
|
||||||
*
|
*
|
||||||
* @see XMLEvent
|
* @see XMLEvent
|
||||||
* @throws XMLStreamException
|
* @throws XMLStreamException
|
||||||
*/
|
*/
|
||||||
public XMLEvent peek() throws XMLStreamException {
|
public XMLEvent peek() throws XMLStreamException {
|
||||||
return (recorder.hasNext()) ? recorder.peek() : parent.peek();
|
return (recorder.hasNext()) ? recorder.peek() : wrappedEventReader.peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next element in the iteration. Calling this method repeatedly
|
|
||||||
* until the {@link #hasNext()} method returns false will return each
|
|
||||||
* element in the underlying collection exactly once.
|
|
||||||
*
|
|
||||||
* @return the next element in the iteration.
|
|
||||||
* @exception NoSuchElementException iteration has no more elements.
|
|
||||||
*/
|
|
||||||
public Object next() {
|
|
||||||
try {
|
|
||||||
return nextEvent();
|
|
||||||
}
|
|
||||||
catch (XMLStreamException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In this implementation throws UnsupportedOperationException.
|
* In this implementation throws UnsupportedOperationException.
|
||||||
*/
|
*/
|
||||||
public void remove() {
|
public void remove() {
|
||||||
throw new java.lang.UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package org.springframework.batch.io.stax;
|
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.XMLEventWriter;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.events.XMLEvent;
|
import javax.xml.stream.events.XMLEvent;
|
||||||
@@ -11,52 +9,17 @@ import javax.xml.stream.events.XMLEvent;
|
|||||||
* but passes through everything else.
|
* but passes through everything else.
|
||||||
*
|
*
|
||||||
* @author peter.zozom
|
* @author peter.zozom
|
||||||
|
* @author Robert Kasanicky
|
||||||
*/
|
*/
|
||||||
class NoStartEndDocumentStreamWriter implements XMLEventWriter {
|
class NoStartEndDocumentStreamWriter extends AbstractEventWriterWrapper {
|
||||||
|
|
||||||
private XMLEventWriter delegate;
|
|
||||||
|
|
||||||
public NoStartEndDocumentStreamWriter(XMLEventWriter delegate) {
|
public NoStartEndDocumentStreamWriter(XMLEventWriter wrappedEventWriter) {
|
||||||
this.delegate = delegate;
|
super(wrappedEventWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(XMLEvent event) throws XMLStreamException {
|
public void add(XMLEvent event) throws XMLStreamException {
|
||||||
if ((!event.isStartDocument()) && (!event.isEndDocument())) {
|
if ((!event.isStartDocument()) && (!event.isEndDocument())) {
|
||||||
delegate.add(event);
|
wrappedEventWriter.add(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(XMLEventReader reader) throws XMLStreamException {
|
|
||||||
delegate.add(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws XMLStreamException {
|
|
||||||
delegate.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void flush() throws XMLStreamException {
|
|
||||||
delegate.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NamespaceContext getNamespaceContext() {
|
|
||||||
return delegate.getNamespaceContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPrefix(String uri) throws XMLStreamException {
|
|
||||||
return delegate.getPrefix(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDefaultNamespace(String uri) throws XMLStreamException {
|
|
||||||
delegate.setDefaultNamespace(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNamespaceContext(NamespaceContext context)
|
|
||||||
throws XMLStreamException {
|
|
||||||
delegate.setNamespaceContext(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrefix(String prefix, String uri) throws XMLStreamException {
|
|
||||||
delegate.setPrefix(prefix, uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,25 +8,28 @@ import org.springframework.util.Assert;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for files used in batch processing.
|
* Utility methods for files used in batch processing.
|
||||||
*
|
*
|
||||||
* @author peter.zozom
|
* @author Peter Zozom
|
||||||
*/
|
*/
|
||||||
public class FileUtils {
|
public class FileUtils {
|
||||||
|
|
||||||
|
// forbids instantiation
|
||||||
|
private FileUtils() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up output file for batch processing. This method implements common logic for
|
* Set up output file for batch processing. This method implements common logic for
|
||||||
* handling output files when starting or restarting job/step.
|
* handling output files when starting or restarting job/step.
|
||||||
* <p> When starting output file processing, method creates/overwrites new file.
|
* When starting output file processing, method creates/overwrites new file.
|
||||||
* When restaring output file processing, method checks whether file is writable.
|
* When restarting output file processing, method checks whether file is writable.
|
||||||
*
|
*
|
||||||
* @param file file to be set up
|
* @param file file to be set up
|
||||||
* @param restarted TRUE signalizes that we are restarting output file processing
|
* @param restarted TRUE signalizes that we are restarting output file processing
|
||||||
* @param overwriteOutputFile If set to TRUE, output file will be overwritten
|
* @param overwriteOutputFile If set to TRUE, output file will be overwritten
|
||||||
* (this flag is ignored when processing is restart)
|
* (this flag is ignored when processing is restart)
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException when file is NULL
|
* @throws IllegalArgumentException when file is NULL
|
||||||
* @throws IllegalStateException when staring output file processing, file exists and
|
* @throws IllegalStateException when staring output file processing, file exists and
|
||||||
* flag "shouldDeleteExisting" is set to FALSE
|
* flag "shouldDeleteExisting" is set to FALSE
|
||||||
* @throws DataAccessResourceFailureException when unable to create file or file is not writable
|
* @throws DataAccessResourceFailureException when unable to create file or file is not writable
|
||||||
*/
|
*/
|
||||||
public static void setUpOutputFile(File file, boolean restarted,
|
public static void setUpOutputFile(File file, boolean restarted,
|
||||||
@@ -37,8 +40,10 @@ public class FileUtils {
|
|||||||
try {
|
try {
|
||||||
if (!restarted) {
|
if (!restarted) {
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
Assert.state(overwriteOutputFile, "File already exists: ["
|
if(!overwriteOutputFile){
|
||||||
+ file.getAbsolutePath() + "]");
|
throw new DataAccessResourceFailureException("File already exists: ["
|
||||||
|
+ file.getAbsolutePath() + "]");
|
||||||
|
}
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ public class MarshallingObjectToXmlSerializerTests extends TestCase {
|
|||||||
mockMarshaller.setThrowException(true);
|
mockMarshaller.setThrowException(true);
|
||||||
try{
|
try{
|
||||||
xmlSerializer.serializeObject(new Object());
|
xmlSerializer.serializeObject(new Object());
|
||||||
|
fail("Exception expected");
|
||||||
}catch(DataAccessResourceFailureException ex){
|
}catch(DataAccessResourceFailureException ex){
|
||||||
//expected
|
//expected
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package org.springframework.batch.io.oxm;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
import javax.xml.stream.XMLInputFactory;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.easymock.MockControl;
|
||||||
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.oxm.Unmarshaller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link UnmarshallingFragmentDeserializer}
|
||||||
|
*
|
||||||
|
* @author Robert Kasanicky
|
||||||
|
*/
|
||||||
|
public class UnmarshallingFragmentDeserializerTests extends TestCase {
|
||||||
|
|
||||||
|
// object under test
|
||||||
|
private UnmarshallingFragmentDeserializer deserializer;
|
||||||
|
|
||||||
|
private XMLEventReader eventReader;
|
||||||
|
private String xml = "<root> </root>";
|
||||||
|
|
||||||
|
private Unmarshaller unmarshaller;
|
||||||
|
private MockControl unmarshallerControl = MockControl.createStrictControl(Unmarshaller.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
Resource input = new ByteArrayResource(xml.getBytes());
|
||||||
|
eventReader = XMLInputFactory.newInstance().createXMLEventReader(input.getInputStream());
|
||||||
|
unmarshaller = (Unmarshaller) unmarshallerControl.getMock();
|
||||||
|
unmarshallerControl.setDefaultMatcher(MockControl.ALWAYS_MATCHER);
|
||||||
|
deserializer = new UnmarshallingFragmentDeserializer(unmarshaller);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regular scenario when deserializer returns the object provided by Unmarshaller
|
||||||
|
*/
|
||||||
|
public void testSuccessfulDeserialization() throws Exception {
|
||||||
|
Object expectedResult = new Object();
|
||||||
|
unmarshaller.unmarshal(null);
|
||||||
|
unmarshallerControl.setReturnValue(expectedResult);
|
||||||
|
unmarshallerControl.replay();
|
||||||
|
|
||||||
|
Object result = deserializer.deserializeFragment(eventReader);
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result);
|
||||||
|
|
||||||
|
unmarshallerControl.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appropriate exception rethrown in case of failure.
|
||||||
|
*/
|
||||||
|
public void testFailedDeserialization() throws Exception {
|
||||||
|
unmarshaller.unmarshal(null);
|
||||||
|
unmarshallerControl.setThrowable(new IOException());
|
||||||
|
unmarshallerControl.replay();
|
||||||
|
|
||||||
|
try {
|
||||||
|
deserializer.deserializeFragment(eventReader);
|
||||||
|
fail("Exception expected");
|
||||||
|
}
|
||||||
|
catch (DataAccessException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
unmarshallerControl.verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It makes no sense to create UnmarshallingFragmentDeserializer with null Unmarshaller,
|
||||||
|
* therefore it should cause exception.
|
||||||
|
*/
|
||||||
|
public void testExceptionOnNullUnmarshaller() {
|
||||||
|
try {
|
||||||
|
deserializer = new UnmarshallingFragmentDeserializer(null);
|
||||||
|
fail("Exception expected");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ public class DefaultTransactionalEventReaderTests extends TestCase {
|
|||||||
* Rollback scenario.
|
* Rollback scenario.
|
||||||
*/
|
*/
|
||||||
public void testRollback() throws Exception {
|
public void testRollback() throws Exception {
|
||||||
|
assertTrue(reader.hasNext());
|
||||||
reader.nextEvent(); //start document
|
reader.nextEvent(); //start document
|
||||||
reader.nextEvent(); //start root element
|
reader.nextEvent(); //start root element
|
||||||
reader.nextEvent(); //whitespace
|
reader.nextEvent(); //whitespace
|
||||||
@@ -44,8 +45,22 @@ public class DefaultTransactionalEventReaderTests extends TestCase {
|
|||||||
assertTrue(EventHelper.endElementName(reader.peek()).equals("misc1"));
|
assertTrue(EventHelper.endElementName(reader.peek()).equals("misc1"));
|
||||||
|
|
||||||
reader.onRollback(); // now we should be at the last commit point
|
reader.onRollback(); // now we should be at the last commit point
|
||||||
|
assertTrue(reader.hasNext());
|
||||||
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("fragment"));
|
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("fragment"));
|
||||||
reader.nextEvent();
|
reader.nextEvent();
|
||||||
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("misc1"));
|
assertTrue(EventHelper.startElementName(reader.nextEvent()).equals("misc1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove operation is not supported
|
||||||
|
*/
|
||||||
|
public void testRemove() {
|
||||||
|
try {
|
||||||
|
reader.remove();
|
||||||
|
fail("UnsupportedOperationException expected on calling remove()");
|
||||||
|
}
|
||||||
|
catch (UnsupportedOperationException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.springframework.batch.io.stax;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLEventFactory;
|
||||||
|
import javax.xml.stream.XMLEventWriter;
|
||||||
|
import javax.xml.stream.events.XMLEvent;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.easymock.MockControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link NoStartEndDocumentStreamWriter}
|
||||||
|
*
|
||||||
|
* @author Robert Kasanicky
|
||||||
|
*/
|
||||||
|
public class NoStartEndDocumentWriterTests extends TestCase {
|
||||||
|
|
||||||
|
// object under test
|
||||||
|
private NoStartEndDocumentStreamWriter writer;
|
||||||
|
|
||||||
|
private XMLEventWriter wrappedWriter;
|
||||||
|
private MockControl wrappedWriterControl = MockControl.createStrictControl(XMLEventWriter.class);
|
||||||
|
|
||||||
|
private XMLEventFactory eventFactory = XMLEventFactory.newInstance();
|
||||||
|
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
wrappedWriter = (XMLEventWriter) wrappedWriterControl.getMock();
|
||||||
|
writer = new NoStartEndDocumentStreamWriter(wrappedWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StartDocument and EndDocument events are not passed to the wrapped writer.
|
||||||
|
*/
|
||||||
|
public void testNoStartEnd() throws Exception {
|
||||||
|
XMLEvent event = eventFactory.createComment("testEvent");
|
||||||
|
|
||||||
|
//mock expects only a single event
|
||||||
|
wrappedWriter.add(event);
|
||||||
|
wrappedWriterControl.setVoidCallable();
|
||||||
|
wrappedWriterControl.replay();
|
||||||
|
|
||||||
|
writer.add(eventFactory.createStartDocument());
|
||||||
|
writer.add(event);
|
||||||
|
writer.add(eventFactory.createEndDocument());
|
||||||
|
|
||||||
|
wrappedWriterControl.verify();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package org.springframework.batch.io.stax;
|
package org.springframework.batch.io.stax;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@@ -15,13 +18,15 @@ import javax.xml.stream.events.XMLEvent;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.springframework.batch.restart.RestartData;
|
import org.springframework.batch.restart.RestartData;
|
||||||
|
import org.springframework.core.io.AbstractResource;
|
||||||
import org.springframework.core.io.ByteArrayResource;
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
import org.springframework.transaction.support.TransactionSynchronization;
|
import org.springframework.transaction.support.TransactionSynchronization;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link StaxEventReaderInputSource}.
|
* Tests for {@link StaxEventReaderInputSource}.
|
||||||
*
|
*
|
||||||
* @author Robert Kasanicky
|
* @author Robert Kasanicky
|
||||||
*/
|
*/
|
||||||
public class StaxEventReaderInputSourceTests extends TestCase {
|
public class StaxEventReaderInputSourceTests extends TestCase {
|
||||||
@@ -32,7 +37,7 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
// test xml input
|
// test xml input
|
||||||
private String xml = "<root> <fragment> <misc1/> </fragment> <misc2/> <fragment> testString </fragment> </root>";
|
private String xml = "<root> <fragment> <misc1/> </fragment> <misc2/> <fragment> testString </fragment> </root>";
|
||||||
|
|
||||||
private FragmentDeserializer deserializer = new FragmentDeserializerMock();
|
private FragmentDeserializer deserializer = new MockFragmentDeserializer();
|
||||||
|
|
||||||
private static final String FRAGMENT_ROOT_ELEMENT = "fragment";
|
private static final String FRAGMENT_ROOT_ELEMENT = "fragment";
|
||||||
|
|
||||||
@@ -40,15 +45,34 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
source = createNewInputSouce();
|
source = createNewInputSouce();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAfterPropertiesSet() throws Exception{
|
||||||
|
source.afterPropertiesSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAfterPropertesSetException() throws Exception{
|
||||||
|
source.setResource(null);
|
||||||
|
try{
|
||||||
|
source.afterPropertiesSet();
|
||||||
|
fail();
|
||||||
|
}catch(IllegalArgumentException ex){
|
||||||
|
//expected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Regular usage scenario.
|
||||||
* InputSource should pass XML fragments to deserializer wrapped with
|
* InputSource should pass XML fragments to deserializer wrapped with
|
||||||
* StartDocument and EndDocument events.
|
* StartDocument and EndDocument events.
|
||||||
*/
|
*/
|
||||||
public void testFragmentWrapping() {
|
public void testFragmentWrapping() throws Exception {
|
||||||
|
source.afterPropertiesSet();
|
||||||
|
|
||||||
// see asserts in the mock deserializer
|
// see asserts in the mock deserializer
|
||||||
assertNotNull(source.read());
|
assertNotNull(source.read());
|
||||||
assertNotNull(source.read());
|
assertNotNull(source.read());
|
||||||
assertNull(source.read()); // there are only two fragments
|
assertNull(source.read()); // there are only two fragments
|
||||||
|
|
||||||
|
source.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -95,10 +119,10 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rollback to last commited record.
|
* Rollback to last commited record.
|
||||||
*/
|
*/
|
||||||
public void testRollback() {
|
public void testRollback() {
|
||||||
|
|
||||||
//rollback between deserializing records
|
//rollback between deserializing records
|
||||||
List first = (List) source.read();
|
List first = (List) source.read();
|
||||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||||
@@ -107,8 +131,8 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||||
|
|
||||||
assertEquals(second, source.read());
|
assertEquals(second, source.read());
|
||||||
|
|
||||||
|
|
||||||
//rollback while deserializing record
|
//rollback while deserializing record
|
||||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||||
source.setFragmentDeserializer(new ExceptionFragmentDeserializer());
|
source.setFragmentDeserializer(new ExceptionFragmentDeserializer());
|
||||||
@@ -119,7 +143,7 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||||
}
|
}
|
||||||
source.setFragmentDeserializer(deserializer);
|
source.setFragmentDeserializer(deserializer);
|
||||||
|
|
||||||
assertEquals(second, source.read());
|
assertEquals(second, source.read());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +165,45 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
assertEquals(NUMBER_OF_RECORDS, extractRecordCountFrom(source.getStatistics()));
|
assertEquals(NUMBER_OF_RECORDS, extractRecordCountFrom(source.getStatistics()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testClose() throws Exception{
|
||||||
|
|
||||||
|
MockStaxEventReaderInputSource newSource = new MockStaxEventReaderInputSource();
|
||||||
|
Resource resource = new ByteArrayResource(xml.getBytes());
|
||||||
|
newSource.setResource(resource);
|
||||||
|
|
||||||
|
newSource.setFragmentRootElementName(FRAGMENT_ROOT_ELEMENT);
|
||||||
|
newSource.setFragmentDeserializer(deserializer);
|
||||||
|
|
||||||
|
Object item = newSource.read();
|
||||||
|
assertNotNull(item);
|
||||||
|
assertTrue(newSource.isOpenCalled());
|
||||||
|
|
||||||
|
newSource.destroy();
|
||||||
|
newSource.setOpenCalled(false);
|
||||||
|
//calling read again should require re-initialization because of close
|
||||||
|
item = newSource.read();
|
||||||
|
assertNotNull(item);
|
||||||
|
assertTrue(newSource.isOpenCalled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOpenBadIOInput(){
|
||||||
|
|
||||||
|
source.setResource(new AbstractResource(){
|
||||||
|
public String getDescription() { return null; }
|
||||||
|
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try{
|
||||||
|
source.open();
|
||||||
|
}catch(DataAccessResourceFailureException ex){
|
||||||
|
assertTrue(ex.getCause() instanceof IOException);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private int extractRecordCountFrom(Properties statistics) {
|
private int extractRecordCountFrom(Properties statistics) {
|
||||||
return Integer.valueOf(
|
return Integer.valueOf(
|
||||||
source.getStatistics().getProperty(StaxEventReaderInputSource.READ_COUNT_STATISTICS_NAME)).intValue();
|
source.getStatistics().getProperty(StaxEventReaderInputSource.READ_COUNT_STATISTICS_NAME)).intValue();
|
||||||
@@ -163,7 +226,7 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
* document events for the fragment root & end tags + skips the fragment
|
* document events for the fragment root & end tags + skips the fragment
|
||||||
* contents.
|
* contents.
|
||||||
*/
|
*/
|
||||||
private static class FragmentDeserializerMock implements FragmentDeserializer {
|
private static class MockFragmentDeserializer implements FragmentDeserializer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple mapFragment implementation checking the
|
* A simple mapFragment implementation checking the
|
||||||
@@ -225,7 +288,7 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
/**
|
/**
|
||||||
* Moves cursor inside the fragment body and causes rollback.
|
* Moves cursor inside the fragment body and causes rollback.
|
||||||
*/
|
*/
|
||||||
private class ExceptionFragmentDeserializer implements FragmentDeserializer {
|
private static class ExceptionFragmentDeserializer implements FragmentDeserializer {
|
||||||
|
|
||||||
public Object deserializeFragment(XMLEventReader eventReader) {
|
public Object deserializeFragment(XMLEventReader eventReader) {
|
||||||
eventReader.next();
|
eventReader.next();
|
||||||
@@ -234,4 +297,21 @@ public class StaxEventReaderInputSourceTests extends TestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class MockStaxEventReaderInputSource extends StaxEventReaderInputSource {
|
||||||
|
|
||||||
|
private boolean openCalled = false;
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
super.open();
|
||||||
|
openCalled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOpenCalled() {
|
||||||
|
return openCalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpenCalled(boolean openCalled) {
|
||||||
|
this.openCalled = openCalled;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package org.springframework.batch.io.support;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.springframework.dao.DataAccessResourceFailureException;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link FileUtils}
|
||||||
|
*
|
||||||
|
* @author Robert Kasanicky
|
||||||
|
*/
|
||||||
|
public class FileUtilsTests extends TestCase {
|
||||||
|
|
||||||
|
private File file = new File("FileUtilsTests.tmp");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No restart + file should not be overwritten => file is created if it does
|
||||||
|
* not exist, exception is thrown if it already exists
|
||||||
|
*/
|
||||||
|
public void testNoRestart() throws Exception {
|
||||||
|
FileUtils.setUpOutputFile(file, false, false);
|
||||||
|
assertTrue(file.exists());
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileUtils.setUpOutputFile(file, false, false);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
file.delete();
|
||||||
|
Assert.state(!file.exists());
|
||||||
|
|
||||||
|
FileUtils.setUpOutputFile(file, false, true);
|
||||||
|
assertTrue(file.exists());
|
||||||
|
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||||
|
writer.write("testString");
|
||||||
|
writer.close();
|
||||||
|
long size = file.length();
|
||||||
|
Assert.state(size > 0);
|
||||||
|
|
||||||
|
FileUtils.setUpOutputFile(file, false, true);
|
||||||
|
long newSize = file.length();
|
||||||
|
|
||||||
|
assertTrue(size != newSize);
|
||||||
|
assertEquals(0, newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In case of restart, the file is supposed to exist and exception is thrown
|
||||||
|
* if it does not.
|
||||||
|
*/
|
||||||
|
public void testRestart() throws Exception {
|
||||||
|
try {
|
||||||
|
FileUtils.setUpOutputFile(file, true, false);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (DataAccessResourceFailureException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileUtils.setUpOutputFile(file, true, true);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (DataAccessResourceFailureException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
file.createNewFile();
|
||||||
|
assertTrue(file.exists());
|
||||||
|
|
||||||
|
// with existing file there should be no trouble
|
||||||
|
FileUtils.setUpOutputFile(file, true, false);
|
||||||
|
FileUtils.setUpOutputFile(file, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the directories on the file path do not exist, they should be created
|
||||||
|
*/
|
||||||
|
public void testCreateDirectoryStructure() {
|
||||||
|
File file = new File("testDirectory/testDirectory2/testFile.tmp");
|
||||||
|
File dir1 = new File("testDirectory");
|
||||||
|
File dir2 = new File("testDirectory/testDirectory2");
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileUtils.setUpOutputFile(file, false, false);
|
||||||
|
assertTrue(file.exists());
|
||||||
|
assertTrue(dir1.exists());
|
||||||
|
assertTrue(dir2.exists());
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
file.delete();
|
||||||
|
dir2.delete();
|
||||||
|
dir1.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBadFile(){
|
||||||
|
|
||||||
|
File file = new File("#:/.out");
|
||||||
|
try{
|
||||||
|
FileUtils.setUpOutputFile(file, false, false);
|
||||||
|
fail();
|
||||||
|
}catch(DataAccessResourceFailureException ex){
|
||||||
|
assertTrue(ex.getCause() instanceof IOException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
Assert.state(!file.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void tearDown() throws Exception {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user