Port more NIO changes over from trunk
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/NIO_32_BRANCH@1055375 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
58a6793fdd
commit
c1e2c16412
@ -249,7 +249,25 @@ public class HSSFWorkbook extends POIDocument
|
|||||||
public HSSFWorkbook(DirectoryNode directory, POIFSFileSystem fs, boolean preserveNodes)
|
public HSSFWorkbook(DirectoryNode directory, POIFSFileSystem fs, boolean preserveNodes)
|
||||||
throws IOException
|
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);
|
String workbookName = getWorkbookDirEntryName(directory);
|
||||||
|
|
||||||
this.preserveNodes = preserveNodes;
|
this.preserveNodes = preserveNodes;
|
||||||
|
@ -51,7 +51,7 @@ public final class NPOIFSDocument implements POIFSViewable {
|
|||||||
this._property = property;
|
this._property = property;
|
||||||
this._filesystem = filesystem;
|
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());
|
_stream = new NPOIFSStream(_filesystem.getMiniStore(), property.getStartBlock());
|
||||||
_block_size = _filesystem.getMiniStore().getBlockStoreBlockSize();
|
_block_size = _filesystem.getMiniStore().getBlockStoreBlockSize();
|
||||||
} else {
|
} else {
|
||||||
|
@ -107,7 +107,7 @@ public class NPOIFSFileSystem extends BlockStore
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a POIFSFileSystem from a <tt>File</tt>. This uses less memory than
|
* 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()}
|
* 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
|
* 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)
|
public NPOIFSFileSystem(File file)
|
||||||
throws IOException
|
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();
|
this();
|
||||||
|
|
||||||
// Open the underlying channel
|
try {
|
||||||
FileChannel channel = (new RandomAccessFile(file, "r")).getChannel();
|
// Get the header
|
||||||
|
ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE);
|
||||||
|
IOUtils.readFully(channel, headerBuffer);
|
||||||
|
|
||||||
// Get the header
|
// Have the header processed
|
||||||
ByteBuffer headerBuffer = ByteBuffer.allocate(POIFSConstants.SMALLER_BIG_BLOCK_SIZE);
|
_header = new HeaderBlock(headerBuffer);
|
||||||
IOUtils.readFully(channel, headerBuffer);
|
|
||||||
|
|
||||||
// Have the header processed
|
// Now process the various entries
|
||||||
_header = new HeaderBlock(headerBuffer);
|
_data = new FileBackedDataSource(channel);
|
||||||
|
readCoreContents();
|
||||||
// Now process the various entries
|
} catch(IOException e) {
|
||||||
_data = new FileBackedDataSource(channel);
|
if(closeChannelOnError) {
|
||||||
readCoreContents();
|
channel.close();
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -435,7 +484,7 @@ public class NPOIFSFileSystem extends BlockStore
|
|||||||
// Oh joy, we need a new XBAT too...
|
// Oh joy, we need a new XBAT too...
|
||||||
xbat = createBAT(offset+1, false);
|
xbat = createBAT(offset+1, false);
|
||||||
xbat.setValueAt(0, offset);
|
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
|
// Will go one place higher as XBAT added in
|
||||||
offset++;
|
offset++;
|
||||||
|
@ -54,9 +54,8 @@ public class EncryptedSlideShow
|
|||||||
public static boolean checkIfEncrypted(HSLFSlideShow hss) {
|
public static boolean checkIfEncrypted(HSLFSlideShow hss) {
|
||||||
// Easy way to check - contains a stream
|
// Easy way to check - contains a stream
|
||||||
// "EncryptedSummary"
|
// "EncryptedSummary"
|
||||||
POIFSFileSystem fs = hss.getPOIFSFileSystem();
|
|
||||||
try {
|
try {
|
||||||
fs.getRoot().getEntry("EncryptedSummary");
|
hss.getPOIFSDirectory().getEntry("EncryptedSummary");
|
||||||
return true;
|
return true;
|
||||||
} catch(FileNotFoundException fnfe) {
|
} catch(FileNotFoundException fnfe) {
|
||||||
// Doesn't have encrypted properties
|
// Doesn't have encrypted properties
|
||||||
|
@ -78,6 +78,9 @@ public final class HSLFSlideShow extends POIDocument {
|
|||||||
protected POIFSFileSystem getPOIFSFileSystem() {
|
protected POIFSFileSystem getPOIFSFileSystem() {
|
||||||
return directory.getFileSystem();
|
return directory.getFileSystem();
|
||||||
}
|
}
|
||||||
|
protected DirectoryNode getPOIFSDirectory() {
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a Powerpoint document from fileName. Parses the document
|
* Constructs a Powerpoint document from fileName. Parses the document
|
||||||
|
@ -163,14 +163,28 @@ public class HWPFDocument extends POIDocument
|
|||||||
* in a POIFSFileSystem, probably not the default.
|
* in a POIFSFileSystem, probably not the default.
|
||||||
* Used typically to open embeded documents.
|
* Used typically to open embeded documents.
|
||||||
*
|
*
|
||||||
|
* @param directory The Directory that contains the Word document.
|
||||||
* @param pfilesystem The POIFSFileSystem 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
|
* @throws IOException If there is an unexpected IOException from the passed
|
||||||
* in POIFSFileSystem.
|
* in POIFSFileSystem.
|
||||||
*/
|
*/
|
||||||
public HWPFDocument(DirectoryNode directory, POIFSFileSystem pfilesystem) throws IOException
|
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
|
// Sort out the hpsf properties
|
||||||
super(directory, pfilesystem);
|
super(directory);
|
||||||
readProperties();
|
readProperties();
|
||||||
|
|
||||||
// read in the main stream.
|
// read in the main stream.
|
||||||
|
@ -28,6 +28,7 @@ import org.apache.poi.hwpf.model.TextPiece;
|
|||||||
import org.apache.poi.hwpf.usermodel.HeaderStories;
|
import org.apache.poi.hwpf.usermodel.HeaderStories;
|
||||||
import org.apache.poi.hwpf.usermodel.Paragraph;
|
import org.apache.poi.hwpf.usermodel.Paragraph;
|
||||||
import org.apache.poi.hwpf.usermodel.Range;
|
import org.apache.poi.hwpf.usermodel.Range;
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +60,15 @@ public class WordExtractor extends POIOLE2TextExtractor {
|
|||||||
this.fs = fs;
|
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
|
* Create a new Word Extractor
|
||||||
* @param doc The HWPFDocument to extract from
|
* @param doc The HWPFDocument to extract from
|
||||||
|
@ -16,12 +16,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.poi.hwpf.extractor;
|
package org.apache.poi.hwpf.extractor;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
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.poifs.filesystem.POIFSFileSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,4 +227,31 @@ public class TestWordExtractor extends TestCase {
|
|||||||
text.indexOf("The footer, with") > -1
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,14 @@ public final class HSSFTestDataSamples {
|
|||||||
* @return an open <tt>InputStream</tt> for the specified sample file
|
* @return an open <tt>InputStream</tt> for the specified sample file
|
||||||
*/
|
*/
|
||||||
public static InputStream openSampleFileStream(String sampleFileName) {
|
public static InputStream openSampleFileStream(String sampleFileName) {
|
||||||
|
File f = getSampeFile(sampleFileName);
|
||||||
|
try {
|
||||||
|
return new FileInputStream(f);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static File getSampeFile(String sampleFileName) {
|
||||||
if(!_isInitialised) {
|
if(!_isInitialised) {
|
||||||
try {
|
try {
|
||||||
initialise();
|
initialise();
|
||||||
@ -56,16 +63,6 @@ public final class HSSFTestDataSamples {
|
|||||||
_isInitialised = true;
|
_isInitialised = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_sampleDataIsAvaliableOnClassPath) {
|
|
||||||
InputStream result = openClasspathResource(sampleFileName);
|
|
||||||
if(result == null) {
|
|
||||||
throw new RuntimeException("specified test sample file '" + sampleFileName
|
|
||||||
+ "' not found on the classpath");
|
|
||||||
}
|
|
||||||
// System.out.println("opening cp: " + sampleFileName);
|
|
||||||
// wrap to avoid temp warning method about auto-closing input stream
|
|
||||||
return new NonSeekableInputStream(result);
|
|
||||||
}
|
|
||||||
if (_resolvedDataDir == null) {
|
if (_resolvedDataDir == null) {
|
||||||
throw new RuntimeException("Must set system property '"
|
throw new RuntimeException("Must set system property '"
|
||||||
+ TEST_DATA_DIR_SYS_PROPERTY_NAME
|
+ TEST_DATA_DIR_SYS_PROPERTY_NAME
|
||||||
@ -78,11 +75,7 @@ public final class HSSFTestDataSamples {
|
|||||||
+ "' not found in data dir '" + _resolvedDataDir.getAbsolutePath() + "'");
|
+ "' not found in data dir '" + _resolvedDataDir.getAbsolutePath() + "'");
|
||||||
}
|
}
|
||||||
// System.out.println("opening " + f.getAbsolutePath());
|
// System.out.println("opening " + f.getAbsolutePath());
|
||||||
try {
|
return f;
|
||||||
return new FileInputStream(f);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initialise() {
|
private static void initialise() {
|
||||||
|
@ -32,6 +32,9 @@ import org.apache.poi.hssf.record.Record;
|
|||||||
import org.apache.poi.hssf.record.RecordFormatException;
|
import org.apache.poi.hssf.record.RecordFormatException;
|
||||||
import org.apache.poi.hssf.record.RecordInputStream;
|
import org.apache.poi.hssf.record.RecordInputStream;
|
||||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
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.LittleEndian;
|
||||||
import org.apache.poi.util.TempFile;
|
import org.apache.poi.util.TempFile;
|
||||||
/**
|
/**
|
||||||
@ -550,4 +553,31 @@ public final class TestHSSFWorkbook extends TestCase {
|
|||||||
nr = wb.getWorkbook().getNameRecord(2);
|
nr = wb.getWorkbook().getNameRecord(2);
|
||||||
assertEquals("Sheet2!E:F,Sheet2!$A$9:$IV$12", nr.getAreaReference(wb)); // E:F,9:12
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user