Finish the POIDocument move, and update HSSFWorkbook to use it

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@577314 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2007-09-19 14:34:31 +00:00
parent 3f7abf9248
commit 63211783d6
3 changed files with 146 additions and 67 deletions

View File

@ -23,6 +23,7 @@
*/ */
package org.apache.poi.hssf.usermodel; package org.apache.poi.hssf.usermodel;
import org.apache.poi.POIDocument;
import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.ddf.EscherBitmapBlip; import org.apache.poi.ddf.EscherBitmapBlip;
import org.apache.poi.ddf.EscherRecord; import org.apache.poi.ddf.EscherRecord;
@ -63,7 +64,7 @@ import java.util.Stack;
* @version 2.0-pre * @version 2.0-pre
*/ */
public class HSSFWorkbook public class HSSFWorkbook extends POIDocument
{ {
private static final int DEBUG = POILogger.DEBUG; private static final int DEBUG = POILogger.DEBUG;
@ -100,12 +101,6 @@ public class HSSFWorkbook
*/ */
private boolean preserveNodes; private boolean preserveNodes;
/**
* if you do preserve the nodes, you'll need to hold the whole POIFS in
* memory.
*/
private POIFSFileSystem poifs;
/** /**
* Used to keep track of the data formatter so that all * Used to keep track of the data formatter so that all
* createDataFormatter calls return the same one for a given * createDataFormatter calls return the same one for a given
@ -160,7 +155,8 @@ public class HSSFWorkbook
* @param fs the POI filesystem that contains the Workbook stream. * @param fs the POI filesystem that contains the Workbook stream.
* @param preserveNodes whether to preseve other nodes, such as * @param preserveNodes whether to preseve other nodes, such as
* macros. This takes more memory, so only say yes if you * macros. This takes more memory, so only say yes if you
* need to. * need to. If set, will store all of the POIFSFileSystem
* in memory
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem * @see org.apache.poi.poifs.filesystem.POIFSFileSystem
* @exception IOException if the stream cannot be read * @exception IOException if the stream cannot be read
*/ */
@ -170,8 +166,14 @@ public class HSSFWorkbook
{ {
this.preserveNodes = preserveNodes; this.preserveNodes = preserveNodes;
if (preserveNodes) { // Read in the HPSF properties
this.poifs = fs; this.filesystem = fs;
readProperties();
// If we're not preserving nodes, don't track the
// POIFS any more
if(! preserveNodes) {
this.filesystem = null;
} }
sheets = new ArrayList(INITIAL_CAPACITY); sheets = new ArrayList(INITIAL_CAPACITY);
@ -904,11 +906,17 @@ public class HSSFWorkbook
byte[] bytes = getBytes(); byte[] bytes = getBytes();
POIFSFileSystem fs = new POIFSFileSystem(); POIFSFileSystem fs = new POIFSFileSystem();
fs.createDocument(new ByteArrayInputStream(bytes), "Workbook"); // For tracking what we've written out, used if we're
// going to be preserving nodes
if (preserveNodes) {
List excepts = new ArrayList(1); List excepts = new ArrayList(1);
// Write out the Workbook stream
fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");
// Write out our HPFS properties, if we have them
writeProperties(fs, excepts);
if (preserveNodes) {
// Don't write out the old Workbook, we'll be doing our new one // Don't write out the old Workbook, we'll be doing our new one
excepts.add("Workbook"); excepts.add("Workbook");
// If the file had WORKBOOK instead of Workbook, we'll write it // If the file had WORKBOOK instead of Workbook, we'll write it
@ -916,7 +924,7 @@ public class HSSFWorkbook
excepts.add("WORKBOOK"); excepts.add("WORKBOOK");
// Copy over all the other nodes to our new poifs // Copy over all the other nodes to our new poifs
copyNodes(this.poifs,fs,excepts); copyNodes(this.filesystem,fs,excepts);
} }
fs.writeFilesystem(stream); fs.writeFilesystem(stream);
//poifs.writeFilesystem(stream); //poifs.writeFilesystem(stream);
@ -1171,58 +1179,6 @@ public class HSSFWorkbook
return new HSSFPalette(workbook.getCustomPalette()); return new HSSFPalette(workbook.getCustomPalette());
} }
/**
* Copies nodes from one POIFS to the other minus the excepts
* @param source is the source POIFS to copy from
* @param target is the target POIFS to copy to
* @param excepts is a list of Strings specifying what nodes NOT to copy
*/
private void copyNodes(POIFSFileSystem source, POIFSFileSystem target,
List excepts) throws IOException {
//System.err.println("CopyNodes called");
DirectoryEntry root = source.getRoot();
DirectoryEntry newRoot = target.getRoot();
Iterator entries = root.getEntries();
while (entries.hasNext()) {
Entry entry = (Entry)entries.next();
if (!isInList(entry.getName(), excepts)) {
copyNodeRecursively(entry,newRoot);
}
}
}
private boolean isInList(String entry, List list) {
for (int k = 0; k < list.size(); k++) {
if (list.get(k).equals(entry)) {
return true;
}
}
return false;
}
private void copyNodeRecursively(Entry entry, DirectoryEntry target)
throws IOException {
//System.err.println("copyNodeRecursively called with "+entry.getName()+
// ","+target.getName());
DirectoryEntry newTarget = null;
if (entry.isDirectoryEntry()) {
newTarget = target.createDirectory(entry.getName());
Iterator entries = ((DirectoryEntry)entry).getEntries();
while (entries.hasNext()) {
copyNodeRecursively((Entry)entries.next(),newTarget);
}
} else {
DocumentEntry dentry = (DocumentEntry)entry;
DocumentInputStream dstream = new DocumentInputStream(dentry);
target.createDocument(dentry.getName(),dstream);
dstream.close();
}
}
/** Test only. Do not use */ /** Test only. Do not use */
public void insertChartRecord() public void insertChartRecord()
{ {
@ -1433,7 +1389,7 @@ public class HSSFWorkbook
Object sub = subRecordIter.next(); Object sub = subRecordIter.next();
if (sub instanceof EmbeddedObjectRefSubRecord) if (sub instanceof EmbeddedObjectRefSubRecord)
{ {
objects.add(new HSSFObjectData((ObjRecord) obj, poifs)); objects.add(new HSSFObjectData((ObjRecord) obj, filesystem));
} }
} }
} }

View File

@ -32,9 +32,12 @@ import org.apache.poi.poifs.filesystem.*;
* Tests that POIDocument correctly loads and saves the common * Tests that POIDocument correctly loads and saves the common
* (hspf) Document Properties * (hspf) Document Properties
* *
* This is part 2 of 2 of the tests - it only does the POIDocuments
* which are part of the scratchpad (not main)
*
* @author Nick Burch (nick at torchbox dot com) * @author Nick Burch (nick at torchbox dot com)
*/ */
public class TestPOIDocument extends TestCase { public class TestPOIDocumentScratchpad extends TestCase {
// The POI Documents to work on // The POI Documents to work on
private POIDocument doc; private POIDocument doc;
private POIDocument doc2; private POIDocument doc2;
@ -49,6 +52,8 @@ public class TestPOIDocument extends TestCase {
public void setUp() throws Exception { public void setUp() throws Exception {
String dirnameHSLF = System.getProperty("HSLF.testdata.path"); String dirnameHSLF = System.getProperty("HSLF.testdata.path");
String filenameHSLF = dirnameHSLF + "/basic_test_ppt_file.ppt"; String filenameHSLF = dirnameHSLF + "/basic_test_ppt_file.ppt";
String dirnameHSSF = System.getProperty("HSSF.testdata.path");
String filenameHSSF = dirnameHSLF + "/DateFormats.ppt";
String dirnameHWPF = System.getProperty("HWPF.testdata.path"); String dirnameHWPF = System.getProperty("HWPF.testdata.path");
String filenameHWPF = dirnameHWPF + "/test2.doc"; String filenameHWPF = dirnameHWPF + "/test2.doc";

View File

@ -0,0 +1,118 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi;
import junit.framework.TestCase;
import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.*;
/**
* Tests that POIDocument correctly loads and saves the common
* (hspf) Document Properties.
*
* This is part 1 of 2 of the tests - it only does the POIDocuments
* which are part of the Main (not scratchpad)
*
* @author Nick Burch (nick at torchbox dot com)
*/
public class TestPOIDocumentMain extends TestCase {
// The POI Documents to work on
private POIDocument doc;
private POIDocument doc2;
// POIFS primed on the test (two different hssf) data
private POIFSFileSystem pfs;
private POIFSFileSystem pfs2;
/**
* Set things up, using a PowerPoint document and
* a Word Document for our testing
*/
public void setUp() throws Exception {
String dirnameHSSF = System.getProperty("HSSF.testdata.path");
String filenameHSSF = dirnameHSSF + "/DateFormats.xls";
String filenameHSSF2 = dirnameHSSF + "/StringFormulas.xls";
FileInputStream fisHSSF = new FileInputStream(filenameHSSF);
pfs = new POIFSFileSystem(fisHSSF);
doc = new HSSFWorkbook(pfs);
FileInputStream fisHSSF2 = new FileInputStream(filenameHSSF2);
pfs2 = new POIFSFileSystem(fisHSSF2);
doc2 = new HSSFWorkbook(pfs2);
}
public void testReadProperties() throws Exception {
// We should have both sets
assertNotNull(doc.getDocumentSummaryInformation());
assertNotNull(doc.getSummaryInformation());
// Check they are as expected for the test doc
assertEquals("Administrator", doc.getSummaryInformation().getAuthor());
assertEquals(0, doc.getDocumentSummaryInformation().getByteCount());
}
public void testReadProperties2() throws Exception {
// Check again on the word one
assertNotNull(doc2.getDocumentSummaryInformation());
assertNotNull(doc2.getSummaryInformation());
assertEquals("Avik Sengupta", doc2.getSummaryInformation().getAuthor());
assertEquals(null, doc2.getSummaryInformation().getKeywords());
assertEquals(0, doc2.getDocumentSummaryInformation().getByteCount());
}
public void testWriteProperties() throws Exception {
// Just check we can write them back out into a filesystem
POIFSFileSystem outFS = new POIFSFileSystem();
doc.writeProperties(outFS);
// Should now hold them
assertNotNull(
outFS.createDocumentInputStream("\005SummaryInformation")
);
assertNotNull(
outFS.createDocumentInputStream("\005DocumentSummaryInformation")
);
}
public void testWriteReadProperties() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Write them out
POIFSFileSystem outFS = new POIFSFileSystem();
doc.writeProperties(outFS);
outFS.writeFilesystem(baos);
// Create a new version
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
POIFSFileSystem inFS = new POIFSFileSystem(bais);
// Check they're still there
doc.filesystem = inFS;
doc.readProperties();
// Delegate test
testReadProperties();
}
}