From 72054fb08dccd1fe1328dd792de79a3f94e752a8 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Wed, 11 Jun 2014 13:48:54 +0000 Subject: [PATCH] Partial fix for #56537 - Have Workbook offer a close() method, which in turn closes the NPOIFS or OPC resource from which it was loaded git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1601901 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hssf/usermodel/HSSFWorkbook.java | 32 +++++++++++++++++-- .../org/apache/poi/ss/usermodel/Workbook.java | 11 ++++++- .../java/org/apache/poi/POIXMLDocument.java | 16 ++++++++++ .../poi/xssf/usermodel/XSSFWorkbook.java | 19 ++++++++--- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 9ad7f87354..5c85368ca4 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -48,7 +48,19 @@ import org.apache.poi.hssf.model.HSSFFormulaParser; import org.apache.poi.hssf.model.InternalSheet; import org.apache.poi.hssf.model.InternalWorkbook; import org.apache.poi.hssf.model.RecordStream; -import org.apache.poi.hssf.record.*; +import org.apache.poi.hssf.record.AbstractEscherHolderRecord; +import org.apache.poi.hssf.record.BackupRecord; +import org.apache.poi.hssf.record.DrawingGroupRecord; +import org.apache.poi.hssf.record.ExtendedFormatRecord; +import org.apache.poi.hssf.record.FontRecord; +import org.apache.poi.hssf.record.LabelRecord; +import org.apache.poi.hssf.record.LabelSSTRecord; +import org.apache.poi.hssf.record.NameRecord; +import org.apache.poi.hssf.record.RecalcIdRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RecordFactory; +import org.apache.poi.hssf.record.SSTRecord; +import org.apache.poi.hssf.record.UnknownRecord; import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; import org.apache.poi.hssf.record.common.UnicodeString; import org.apache.poi.hssf.util.CellReference; @@ -56,6 +68,7 @@ import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.EntryUtils; import org.apache.poi.poifs.filesystem.FilteringDirectoryNode; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.poifs.filesystem.Ole10Native; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.formula.FormulaShifter; @@ -1178,6 +1191,22 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss return style; } + + /** + * Closes the underlying {@link NPOIFSFileSystem} from which + * the Workbook was read, if any. Has no effect on Workbooks + * opened from an InputStream, or newly created ones. + */ + @Override + public void close() throws IOException + { + if (directory != null) { + if (directory.getNFileSystem() != null) { + directory.getNFileSystem().close(); + directory = null; + } + } + } /** * Method write - write out this workbook to an Outputstream. Constructs @@ -1189,7 +1218,6 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss * @exception IOException if anything can't be written. * @see org.apache.poi.poifs.filesystem.POIFSFileSystem */ - @Override public void write(OutputStream stream) throws IOException diff --git a/src/java/org/apache/poi/ss/usermodel/Workbook.java b/src/java/org/apache/poi/ss/usermodel/Workbook.java index a476a74f8c..0ed1a6605d 100644 --- a/src/java/org/apache/poi/ss/usermodel/Workbook.java +++ b/src/java/org/apache/poi/ss/usermodel/Workbook.java @@ -17,6 +17,7 @@ package org.apache.poi.ss.usermodel; +import java.io.Closeable; import java.io.IOException; import java.io.OutputStream; import java.util.List; @@ -30,7 +31,7 @@ import org.apache.poi.ss.util.CellRangeAddress; * will construct whether they are reading or writing a workbook. It is also the * top level object for creating new sheets/etc. */ -public interface Workbook { +public interface Workbook extends Closeable { /** Extended windows meta file */ public static final int PICTURE_TYPE_EMF = 2; @@ -350,6 +351,14 @@ public interface Workbook { */ void write(OutputStream stream) throws IOException; + /** + * Close the underlying input resource (File or Stream), + * from which the Workbook was read. After closing, the + * Workbook should no longer be used. + *

This will have no effect newly created Workbooks. + */ + void close() throws IOException; + /** * @return the total number of defined names in this workbook */ diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java index fa41a5744f..51ba84957c 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -29,6 +29,7 @@ import java.util.Set; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; @@ -159,6 +160,21 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{ onDocumentRead(); context.clear(); } + + /** + * Closes the underlying {@link OPCPackage} from which this + * document was read, if there is one + */ + protected void close() throws IOException { + if (pkg != null) { + if (pkg.getPackageAccess() == PackageAccess.READ) { + pkg.revert(); + } else { + pkg.close(); + } + pkg = null; + } + } /** * Write out this document to an Outputstream. diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 34d8eada76..38818c16d0 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -199,10 +199,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, IterablePackage object, * see http://poi.apache.org/oxml4j/. * - * Once you have finished working with the Workbook, you should close the package - * by calling pkg.close, to avoid leaving file handles open. + *

Once you have finished working with the Workbook, you should close the package + * by calling either {@link #close()} or {@link OPCPackage#close()}, to avoid + * leaving file handles open. * - * Creating a XSSFWorkbook from a file-backed OPC Package has a lower memory + *

Creating a XSSFWorkbook from a file-backed OPC Package has a lower memory * footprint than an InputStream backed one. * * @param pkg the OpenXML4J OPC Package object. @@ -218,7 +219,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, IterableUsing an {@link InputStream} requires more memory than using a File, so * if a {@link File} is available then you should instead do something like *


      *       OPCPackage pkg = OPCPackage.open(path);
@@ -1350,6 +1351,16 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable