]> source.dussan.org Git - poi.git/commitdiff
Port more NIO changes over from trunk
authorNick Burch <nick@apache.org>
Wed, 5 Jan 2011 09:38:10 +0000 (09:38 +0000)
committerNick Burch <nick@apache.org>
Wed, 5 Jan 2011 09:38:10 +0000 (09:38 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/NIO_32_BRANCH@1055375 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
src/scratchpad/src/org/apache/poi/hslf/EncryptedSlideShow.java
src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
src/scratchpad/src/org/apache/poi/hwpf/extractor/WordExtractor.java
src/scratchpad/testcases/org/apache/poi/hwpf/extractor/TestWordExtractor.java
src/testcases/org/apache/poi/hssf/HSSFTestDataSamples.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java

index 3a7ca03fc2196c767af5f334da19359f3119314e..95a567bb5b565ae6009a76d62e4079271bee319b 100644 (file)
@@ -249,7 +249,25 @@ public class HSSFWorkbook extends POIDocument
     public HSSFWorkbook(DirectoryNode directory, POIFSFileSystem fs, boolean preserveNodes)
             throws IOException
     {
-        super(directory, fs);
+       this(directory, preserveNodes);
+    }
+    /**
+     * given a POI POIFSFileSystem object, and a specific directory
+     *  within it, read in its Workbook and populate the high and
+     *  low level models.  If you're reading in a workbook...start here.
+     *
+     * @param directory the POI filesystem directory to process from
+     * @param preserveNodes whether to preseve other nodes, such as
+     *        macros.  This takes more memory, so only say yes if you
+     *        need to. If set, will store all of the POIFSFileSystem
+     *        in memory
+     * @see org.apache.poi.poifs.filesystem.POIFSFileSystem
+     * @exception IOException if the stream cannot be read
+     */
+    public HSSFWorkbook(DirectoryNode directory, boolean preserveNodes)
+            throws IOException
+    {
+        super(directory);
         String workbookName = getWorkbookDirEntryName(directory);
 
         this.preserveNodes = preserveNodes;
index 09536d4ade5e5f2330ca01f77becbcc90ce14393..3a2c28602336e2e0328ee23cdc68a22bfef4f05b 100644 (file)
@@ -51,7 +51,7 @@ public final class NPOIFSDocument implements POIFSViewable {
       this._property = property;
       this._filesystem = filesystem;
 
-      if(property.getSize() <= POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE) {
+      if(property.getSize() < POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE) {
          _stream = new NPOIFSStream(_filesystem.getMiniStore(), property.getStartBlock());
          _block_size = _filesystem.getMiniStore().getBlockStoreBlockSize();
       } else {
index e671d870bb89ba29f6f82f734ab7e94569ef0b36..8a7b6833153b54331be98f3de8cc0d3ab49e0a47 100644 (file)
@@ -107,7 +107,7 @@ public class NPOIFSFileSystem extends BlockStore
 
     /**
      * Creates a POIFSFileSystem from a <tt>File</tt>. This uses less memory than
-     *  creating from an <tt>InputStream</tt>.
+     *  creating from an <tt>InputStream</tt>. The File will be opened read-only
      *  
      * Note that with this constructor, you will need to call {@link #close()}
      *  when you're done to have the underlying file closed, as the file is
@@ -119,22 +119,71 @@ public class NPOIFSFileSystem extends BlockStore
      */
     public NPOIFSFileSystem(File file)
          throws IOException
+    {
+       this(file, true);
+    }
+    
+    /**
+     * Creates a POIFSFileSystem from a <tt>File</tt>. This uses less memory than
+     *  creating from an <tt>InputStream</tt>.
+     *  
+     * Note that with this constructor, you will need to call {@link #close()}
+     *  when you're done to have the underlying file closed, as the file is
+     *  kept open during normal operation to read the data out. 
+     *  
+     * @param file the File from which to read the data
+     *
+     * @exception IOException on errors reading, or on invalid data
+     */
+    public NPOIFSFileSystem(File file, boolean readOnly)
+         throws IOException
+    {
+       this(
+           (new RandomAccessFile(file, readOnly? "r" : "rw")).getChannel(),
+           true
+       );
+    }
+    
+    /**
+     * Creates a POIFSFileSystem from an open <tt>FileChannel</tt>. This uses 
+     *  less memory than creating from an <tt>InputStream</tt>.
+     *  
+     * Note that with this constructor, you will need to call {@link #close()}
+     *  when you're done to have the underlying Channel closed, as the channel is
+     *  kept open during normal operation to read the data out. 
+     *  
+     * @param channel the FileChannel from which to read the data
+     *
+     * @exception IOException on errors reading, or on invalid data
+     */
+    public NPOIFSFileSystem(FileChannel channel)
+         throws IOException
+    {
+       this(channel, false);
+    }
+    
+    private NPOIFSFileSystem(FileChannel channel, boolean closeChannelOnError)
+         throws IOException
     {
        this();
-       
-       // Open the underlying channel
-       FileChannel channel = (new RandomAccessFile(file, "r")).getChannel();
-       
-       // Get the header
-       ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE);
-       IOUtils.readFully(channel, headerBuffer);
-       
-       // Have the header processed
-       _header = new HeaderBlock(headerBuffer);
-       
-       // Now process the various entries
-       _data = new FileBackedDataSource(channel);
-       readCoreContents();
+
+       try {
+          // Get the header
+          ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE);
+          IOUtils.readFully(channel, headerBuffer);
+          
+          // Have the header processed
+          _header = new HeaderBlock(headerBuffer);
+          
+          // Now process the various entries
+          _data = new FileBackedDataSource(channel);
+          readCoreContents();
+       } catch(IOException e) {
+          if(closeChannelOnError) {
+             channel.close();
+          }
+          throw e;
+       }
     }
     
     /**
@@ -435,7 +484,7 @@ public class NPOIFSFileSystem extends BlockStore
              // Oh joy, we need a new XBAT too...
              xbat = createBAT(offset+1, false);
              xbat.setValueAt(0, offset);
-             bat.setValueAt(offset+1, POIFSConstants.DIFAT_SECTOR_BLOCK);
+             bat.setValueAt(1, POIFSConstants.DIFAT_SECTOR_BLOCK);
              
              // Will go one place higher as XBAT added in
              offset++;
index 15625fd2a85d321413d90713b4ad1a4d105ab909..5170436c01d1a523a98c2a1047093e484c507829 100644 (file)
@@ -54,9 +54,8 @@ public class EncryptedSlideShow
        public static boolean checkIfEncrypted(HSLFSlideShow hss) {
                // Easy way to check - contains a stream
                //  "EncryptedSummary"
-               POIFSFileSystem fs = hss.getPOIFSFileSystem();
                try {
-                       fs.getRoot().getEntry("EncryptedSummary");
+                       hss.getPOIFSDirectory().getEntry("EncryptedSummary");
                        return true;
                } catch(FileNotFoundException fnfe) {
                        // Doesn't have encrypted properties
index c024b47eee0159efb8e3ac73d8dc9815cf5e2bfb..a710ec933879f58470e20766c2b70a3b573ad810 100644 (file)
@@ -78,6 +78,9 @@ public final class HSLFSlideShow extends POIDocument {
        protected POIFSFileSystem getPOIFSFileSystem() {
                return directory.getFileSystem();
        }
+       protected DirectoryNode getPOIFSDirectory() {
+               return directory;
+       }
 
        /**
         * Constructs a Powerpoint document from fileName. Parses the document 
index 4186071bc8a2728d4b1b165f9ccbd5c12500bcaf..f1e1d8a9a295a1e3a326aa310e6082087100cc89 100644 (file)
@@ -163,14 +163,28 @@ public class HWPFDocument extends POIDocument
    *  in a POIFSFileSystem, probably not the default.
    * Used typically to open embeded documents.
    *
+   * @param directory The Directory that contains the Word document.
    * @param pfilesystem The POIFSFileSystem that contains the Word document.
    * @throws IOException If there is an unexpected IOException from the passed
    *         in POIFSFileSystem.
    */
   public HWPFDocument(DirectoryNode directory, POIFSFileSystem pfilesystem) throws IOException
+  {
+    this(directory);
+  }
+  /**
+   * This constructor loads a Word document from a specific point
+   *  in a POIFSFileSystem, probably not the default.
+   * Used typically to open embeded documents.
+   *
+   * @param directory The Directory that contains the Word document.
+   * @throws IOException If there is an unexpected IOException from the passed
+   *         in POIFSFileSystem.
+   */
+  public HWPFDocument(DirectoryNode directory) throws IOException
   {
     // Sort out the hpsf properties
-       super(directory, pfilesystem);
+       super(directory);
     readProperties();
     
     // read in the main stream.
index deaffc79afba891ae1c89d91d1a770203e03f81a..64981e94e733e68b39fdffb55652a26d1c2716dd 100644 (file)
@@ -28,6 +28,7 @@ import org.apache.poi.hwpf.model.TextPiece;
 import org.apache.poi.hwpf.usermodel.HeaderStories;
 import org.apache.poi.hwpf.usermodel.Paragraph;
 import org.apache.poi.hwpf.usermodel.Range;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
 /**
@@ -59,6 +60,15 @@ public class WordExtractor extends POIOLE2TextExtractor {
                this.fs = fs;
        }
        
+       /**
+        * Create a new Word Extractor
+        * @param dir DirectoryNode containing the word file
+        */
+       public WordExtractor(DirectoryNode dir) throws IOException {
+               this(new HWPFDocument(dir));
+               this.fs = fs;
+       }
+       
        /**
         * Create a new Word Extractor
         * @param doc The HWPFDocument to extract from
index a1b78752f818d4807b5049d5c616f4bc306afb84..a32232ae6610d3a5bc568fae6205e46e17c55cd0 100644 (file)
 */
 package org.apache.poi.hwpf.extractor;
 
+import java.io.File;
 import java.io.FileInputStream;
 
 import junit.framework.TestCase;
 
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
 /**
@@ -225,4 +227,31 @@ public class TestWordExtractor extends TestCase {
                        text.indexOf("The footer, with") > -1
        );
     }
+    
+    /**
+     * Tests that we can work with both {@link POIFSFileSystem}
+     *  and {@link NPOIFSFileSystem}
+     */
+    public void testDifferentPOIFS() throws Exception {
+                String dirname = System.getProperty("HWPF.testdata.path");
+       File f = new File(dirname, "test2.doc");
+       
+       // Open the two filesystems
+       DirectoryNode[] files = new DirectoryNode[2];
+       files[0] = (new POIFSFileSystem(new FileInputStream(f))).getRoot();
+       files[1] = (new NPOIFSFileSystem(f)).getRoot();
+       
+       // Open directly 
+       for(DirectoryNode dir : files) {
+          WordExtractor extractor = new WordExtractor(dir);
+          assertEquals(p_text1_block, extractor.getText());
+       }
+
+       // Open via a HWPFDocument
+       for(DirectoryNode dir : files) {
+          HWPFDocument doc = new HWPFDocument(dir);
+          WordExtractor extractor = new WordExtractor(doc);
+          assertEquals(p_text1_block, extractor.getText());
+       }
+    }
 }
index 0e64637f97280aa3897ebfd894e5eff63fdd8cb0..bf9113a3dee111662c07a7b4ca43b30ad12a59c9 100644 (file)
@@ -48,7 +48,14 @@ public final class HSSFTestDataSamples {
         * @return an open <tt>InputStream</tt> for the specified sample file\r
         */\r
        public static InputStream openSampleFileStream(String sampleFileName) {\r
-               \r
+      File f = getSampeFile(sampleFileName);\r
+               try {\r
+                       return new FileInputStream(f);\r
+               } catch (FileNotFoundException e) {\r
+                       throw new RuntimeException(e);\r
+               }\r
+   }\r
+       public static File getSampeFile(String sampleFileName) {\r
                if(!_isInitialised) {\r
                        try {\r
                                initialise();\r
@@ -56,16 +63,6 @@ public final class HSSFTestDataSamples {
                                _isInitialised = true;\r
                        }\r
                }\r
-               if (_sampleDataIsAvaliableOnClassPath) {\r
-                       InputStream result = openClasspathResource(sampleFileName);\r
-                       if(result == null) {\r
-                               throw new RuntimeException("specified test sample file '" + sampleFileName \r
-                                               + "' not found on the classpath");\r
-                       }\r
-//                     System.out.println("opening cp: " + sampleFileName);\r
-                       // wrap to avoid temp warning method about auto-closing input stream\r
-                       return new NonSeekableInputStream(result);\r
-               }\r
                if (_resolvedDataDir == null) {\r
                        throw new RuntimeException("Must set system property '"\r
                                        + TEST_DATA_DIR_SYS_PROPERTY_NAME\r
@@ -78,11 +75,7 @@ public final class HSSFTestDataSamples {
                                        + "' not found in data dir '" + _resolvedDataDir.getAbsolutePath() + "'");\r
                }\r
 //             System.out.println("opening " + f.getAbsolutePath());\r
-               try {\r
-                       return new FileInputStream(f);\r
-               } catch (FileNotFoundException e) {\r
-                       throw new RuntimeException(e);\r
-               }\r
+      return f;\r
        }\r
 \r
        private static void initialise() {\r
index 4357c57e3b2e028afc1effec77422265411521ac..cd734a66da1ad066220edc8d4db6cd2b6c10088b 100644 (file)
@@ -32,6 +32,9 @@ import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RecordFormatException;
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.TempFile;
 /**
@@ -550,4 +553,31 @@ public final class TestHSSFWorkbook extends TestCase {
         nr = wb.getWorkbook().getNameRecord(2);
         assertEquals("Sheet2!E:F,Sheet2!$A$9:$IV$12", nr.getAreaReference(wb)); // E:F,9:12
     }
+
+    /**
+     * Tests that we can work with both {@link POIFSFileSystem}
+     *  and {@link NPOIFSFileSystem}
+     */
+    public void testDifferentPOIFS() throws Exception {
+       // Open the two filesystems
+       DirectoryNode[] files = new DirectoryNode[2];
+       files[0] = (new POIFSFileSystem(HSSFTestDataSamples.openSampleFileStream("Simple.xls"))).getRoot();
+       files[1] = (new NPOIFSFileSystem(HSSFTestDataSamples.getSampeFile("Simple.xls"))).getRoot();
+       
+       // Open without preserving nodes 
+       for(DirectoryNode dir : files) {
+          HSSFWorkbook workbook = new HSSFWorkbook(dir, false);
+          HSSFSheet sheet = workbook.getSheetAt(0);
+          HSSFCell cell = sheet.getRow(0).getCell(0);
+          assertEquals("replaceMe", cell .getRichStringCellValue().getString());
+       }
+
+       // Now re-check with preserving
+       for(DirectoryNode dir : files) {
+          HSSFWorkbook workbook = new HSSFWorkbook(dir, true);
+          HSSFSheet sheet = workbook.getSheetAt(0);
+          HSSFCell cell = sheet.getRow(0).getCell(0);
+          assertEquals("replaceMe", cell .getRichStringCellValue().getString());
+       }
+    }
 }