Improve handling and warnings when closing OPCPackage objects
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@982311 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
654c53efc8
commit
3c4946472b
@ -34,6 +34,7 @@
|
||||
|
||||
<changes>
|
||||
<release version="3.7-beta2" date="2010-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="fix">Improve handling and warnings when closing OPCPackage objects</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">49702 - Correct XSSFWorkbook.getNumCellStyles to check the right styles list</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">49690 - Add WorkbookUtil, which provies a way of generating valid sheet names</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">49694 - Use DataFormatter when autosizing columns, to better match the real display width of formatted cells</action>
|
||||
|
@ -338,15 +338,19 @@ public abstract class OPCPackage implements RelationshipSource {
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the package and save its content.
|
||||
* Close the open, writable package and save its content.
|
||||
*
|
||||
* If your package is open read only, then you should call {@link #revert()}
|
||||
* when finished with the package.
|
||||
*
|
||||
* @throws IOException
|
||||
* If an IO exception occur during the saving process.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (this.packageAccess == PackageAccess.READ) {
|
||||
logger
|
||||
.log(POILogger.WARN, "The close() method is intended to SAVE a package. This package is open in READ ONLY mode, use the revert() method instead !");
|
||||
logger.log(POILogger.WARN,
|
||||
"The close() method is intended to SAVE a package. This package is open in READ ONLY mode, use the revert() method instead !");
|
||||
revert();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1298,6 +1302,17 @@ public abstract class OPCPackage implements RelationshipSource {
|
||||
throw new IllegalArgumentException("targetFile");
|
||||
|
||||
this.throwExceptionIfReadOnly();
|
||||
|
||||
// You shouldn't save the the same file, do a close instead
|
||||
if(targetFile.exists() &&
|
||||
targetFile.getAbsolutePath().equals(this.originalPackagePath)) {
|
||||
throw new InvalidOperationException(
|
||||
"You can't call save(File) to save to the currently open " +
|
||||
"file. To save to the current file, please just call close()"
|
||||
);
|
||||
}
|
||||
|
||||
// Do the save
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(targetFile);
|
||||
|
@ -295,8 +295,11 @@ public final class ZipPackage extends Package {
|
||||
// Save the final package to a temporary file
|
||||
try {
|
||||
save(tempFile);
|
||||
this.zipArchive.close(); // Close the zip archive to be
|
||||
// able to delete it
|
||||
|
||||
// Close the current zip file, so we can
|
||||
// overwrite it on all platforms
|
||||
this.zipArchive.close();
|
||||
// Copy the new file over the old one
|
||||
FileHelper.copyFile(tempFile, targetFile);
|
||||
} finally {
|
||||
// Either the save operation succeed or not, we delete the
|
||||
@ -312,7 +315,7 @@ public final class ZipPackage extends Package {
|
||||
throw new InvalidOperationException(
|
||||
"Can't close a package not previously open with the open() method !");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,6 +32,7 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
|
||||
import org.apache.poi.openxml4j.opc.internal.ContentTypeManager;
|
||||
import org.apache.poi.openxml4j.opc.internal.FileHelper;
|
||||
import org.apache.poi.util.TempFile;
|
||||
@ -443,6 +444,64 @@ public final class TestPackage extends TestCase {
|
||||
// Don't save modifications
|
||||
p.revert();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can open a file by path, and then
|
||||
* write changes to it.
|
||||
*/
|
||||
public void testOpenFileThenOverwrite() throws Exception {
|
||||
File tempFile = File.createTempFile("poiTesting","tmp");
|
||||
File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx");
|
||||
FileHelper.copyFile(origFile, tempFile);
|
||||
|
||||
// Open the temp file
|
||||
OPCPackage p = OPCPackage.open(tempFile.toString(), PackageAccess.READ_WRITE);
|
||||
// Close it
|
||||
p.close();
|
||||
// Delete it
|
||||
assertTrue(tempFile.delete());
|
||||
|
||||
// Reset
|
||||
FileHelper.copyFile(origFile, tempFile);
|
||||
p = OPCPackage.open(tempFile.toString(), PackageAccess.READ_WRITE);
|
||||
|
||||
// Save it to the same file - not allowed
|
||||
try {
|
||||
p.save(tempFile);
|
||||
fail("You shouldn't be able to call save(File) to overwrite the current file");
|
||||
} catch(InvalidOperationException e) {}
|
||||
|
||||
// Delete it
|
||||
assertTrue(tempFile.delete());
|
||||
|
||||
|
||||
// Open it read only, then close and delete - allowed
|
||||
FileHelper.copyFile(origFile, tempFile);
|
||||
p = OPCPackage.open(tempFile.toString(), PackageAccess.READ);
|
||||
p.close();
|
||||
assertTrue(tempFile.delete());
|
||||
}
|
||||
/**
|
||||
* Test that we can open a file by path, save it
|
||||
* to another file, then delete both
|
||||
*/
|
||||
public void testOpenFileThenSaveDelete() throws Exception {
|
||||
File tempFile = File.createTempFile("poiTesting","tmp");
|
||||
File tempFile2 = File.createTempFile("poiTesting","tmp");
|
||||
File origFile = OpenXML4JTestDataSamples.getSampleFile("TestPackageCommon.docx");
|
||||
FileHelper.copyFile(origFile, tempFile);
|
||||
|
||||
// Open the temp file
|
||||
OPCPackage p = OPCPackage.open(tempFile.toString(), PackageAccess.READ_WRITE);
|
||||
|
||||
// Save it to a different file
|
||||
p.save(tempFile2);
|
||||
p.close();
|
||||
|
||||
// Delete both the files
|
||||
assertTrue(tempFile.delete());
|
||||
assertTrue(tempFile2.delete());
|
||||
}
|
||||
|
||||
private static ContentTypeManager getContentTypeManager(OPCPackage pkg) throws Exception {
|
||||
Field f = OPCPackage.class.getDeclaredField("contentTypeManager");
|
||||
|
Loading…
Reference in New Issue
Block a user