bug 60102: throw IOException when writing a closed document
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1760206 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7dabe1b101
commit
d9cfcbdd18
@ -40,6 +40,7 @@ import org.apache.xmlbeans.impl.common.SystemCache;
|
|||||||
/**
|
/**
|
||||||
* This holds the common functionality for all POI OOXML Document classes.
|
* This holds the common functionality for all POI OOXML Document classes.
|
||||||
*/
|
*/
|
||||||
|
// TODO: implements AutoCloseable in Java 7+ when POI drops support for Java 6.
|
||||||
public abstract class POIXMLDocument extends POIXMLDocumentPart implements Closeable {
|
public abstract class POIXMLDocument extends POIXMLDocumentPart implements Closeable {
|
||||||
public static final String DOCUMENT_CREATOR = "Apache POI";
|
public static final String DOCUMENT_CREATOR = "Apache POI";
|
||||||
|
|
||||||
@ -230,6 +231,11 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart implements Close
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public final void write(OutputStream stream) throws IOException {
|
public final void write(OutputStream stream) throws IOException {
|
||||||
|
OPCPackage p = getPackage();
|
||||||
|
if(p == null) {
|
||||||
|
throw new IOException("Cannot write data, document seems to have been closed already");
|
||||||
|
}
|
||||||
|
|
||||||
//force all children to commit their changes into the underlying OOXML Package
|
//force all children to commit their changes into the underlying OOXML Package
|
||||||
// TODO Shouldn't they be committing to the new one instead?
|
// TODO Shouldn't they be committing to the new one instead?
|
||||||
Set<PackagePart> context = new HashSet<PackagePart>();
|
Set<PackagePart> context = new HashSet<PackagePart>();
|
||||||
@ -239,10 +245,6 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart implements Close
|
|||||||
//save extended and custom properties
|
//save extended and custom properties
|
||||||
getProperties().commit();
|
getProperties().commit();
|
||||||
|
|
||||||
OPCPackage p = getPackage();
|
|
||||||
if(p == null) {
|
|
||||||
throw new IOException("Cannot write data, document seems to have been closed already");
|
|
||||||
}
|
|
||||||
p.save(stream);
|
p.save(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -33,9 +34,11 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||||
|
import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
|
||||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||||
import org.apache.poi.openxml4j.opc.PackagePart;
|
import org.apache.poi.openxml4j.opc.PackagePart;
|
||||||
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
|
||||||
|
import org.apache.poi.util.NullOutputStream;
|
||||||
import org.apache.poi.util.PackageHelper;
|
import org.apache.poi.util.PackageHelper;
|
||||||
import org.apache.poi.util.TempFile;
|
import org.apache.poi.util.TempFile;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -120,12 +123,43 @@ public final class TestPOIXMLDocument {
|
|||||||
FileOutputStream out = new FileOutputStream(tmp);
|
FileOutputStream out = new FileOutputStream(tmp);
|
||||||
doc.write(out);
|
doc.write(out);
|
||||||
out.close();
|
out.close();
|
||||||
|
|
||||||
|
// Should not be able to write to an output stream that has been closed
|
||||||
|
try {
|
||||||
|
doc.write(out);
|
||||||
|
fail("Should not be able to write to an output stream that has been closed.");
|
||||||
|
} catch (final OpenXML4JRuntimeException e) {
|
||||||
|
// FIXME: A better exception class (IOException?) and message should be raised
|
||||||
|
// indicating that the document could not be written because the output stream is closed.
|
||||||
|
// see {@link org.apache.poi.openxml4j.opc.ZipPackage#saveImpl(java.io.OutputStream)}
|
||||||
|
if (e.getMessage().matches("Fail to save: an error occurs while saving the package : The part .+ fail to be saved in the stream with marshaller .+")) {
|
||||||
|
// expected
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should not be able to write a document that has been closed
|
||||||
doc.close();
|
doc.close();
|
||||||
|
try {
|
||||||
|
doc.write(new NullOutputStream());
|
||||||
|
fail("Should not be able to write a document that has been closed.");
|
||||||
|
} catch (final IOException e) {
|
||||||
|
if (e.getMessage().equals("Cannot write data, document seems to have been closed already")) {
|
||||||
|
// expected
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be able to close a document multiple times, though subsequent closes will have no effect.
|
||||||
|
doc.close();
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
OPCPackage pkg2 = OPCPackage.open(tmp.getAbsolutePath());
|
OPCPackage pkg2 = OPCPackage.open(tmp.getAbsolutePath());
|
||||||
try {
|
|
||||||
doc = new OPCParser(pkg1);
|
doc = new OPCParser(pkg1);
|
||||||
|
try {
|
||||||
doc.parse(new TestFactory());
|
doc.parse(new TestFactory());
|
||||||
context = new HashMap<String,POIXMLDocumentPart>();
|
context = new HashMap<String,POIXMLDocumentPart>();
|
||||||
traverse(doc, context);
|
traverse(doc, context);
|
||||||
@ -150,6 +184,7 @@ public final class TestPOIXMLDocument {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
doc.close();
|
doc.close();
|
||||||
|
pkg1.close();
|
||||||
pkg2.close();
|
pkg2.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user