}
/**
- * 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;
}
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);
// 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
throw new InvalidOperationException(
"Can't close a package not previously open with the open() method !");
}
- }
+ }
}
/**
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;
// 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");