When writing out a HSLF file, optionally also write out all the different OLE2 streams, and not just the normal HSLF related ones

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@576505 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2007-09-17 16:30:31 +00:00
parent 312b7ff2dc
commit ed2d78b08b
4 changed files with 125 additions and 1 deletions

View File

@ -20,13 +20,18 @@ package org.apache.poi;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.MutablePropertySet;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
@ -106,11 +111,25 @@ public abstract class POIDocument {
* @param outFS the POIFSFileSystem to write the properties into
*/
protected void writeProperties(POIFSFileSystem outFS) throws IOException {
writeProperties(outFS, null);
}
/**
* Writes out the standard Documment Information Properties (HPSF)
* @param outFS the POIFSFileSystem to write the properties into
* @param writtenEntries a list of POIFS entries to add the property names too
*/
protected void writeProperties(POIFSFileSystem outFS, List writtenEntries) throws IOException {
if(sInf != null) {
writePropertySet(SummaryInformation.DEFAULT_STREAM_NAME,sInf,outFS);
if(writtenEntries != null) {
writtenEntries.add(SummaryInformation.DEFAULT_STREAM_NAME);
}
}
if(dsInf != null) {
writePropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME,dsInf,outFS);
if(writtenEntries != null) {
writtenEntries.add(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
}
}
}
@ -135,4 +154,63 @@ public abstract class POIDocument {
System.err.println("Couldn't write property set with name " + name + " as not supported by HPSF yet");
}
}
/**
* 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
*/
protected 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);
}
}
}
/**
* Checks to see if the String is in the list, used when copying
* nodes between one POIFS and another
*/
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;
}
/**
* Copies an Entry into a target POIFS directory, recursively
*/
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();
}
}
}

View File

@ -383,8 +383,11 @@ public class HSLFSlideShow extends POIDocument
// Get a new Filesystem to write into
POIFSFileSystem outFS = new POIFSFileSystem();
// The list of entries we've written out
List writtenEntries = new ArrayList(1);
// Write out the Property Streams
writeProperties(outFS);
writeProperties(outFS, writtenEntries);
// For position dependent records, hold where they were and now are
@ -435,6 +438,7 @@ public class HSLFSlideShow extends POIDocument
// Write the PPT stream into the POIFS layer
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
outFS.createDocument(bais,"PowerPoint Document");
writtenEntries.add("PowerPoint Document");
// Update and write out the Current User atom
@ -445,6 +449,7 @@ public class HSLFSlideShow extends POIDocument
}
currentUser.setCurrentEditOffset(newLastUserEditAtomPos.intValue());
currentUser.writeToFS(outFS);
writtenEntries.add("Current User");
// Write any pictures, into another stream
@ -456,6 +461,12 @@ public class HSLFSlideShow extends POIDocument
outFS.createDocument(
new ByteArrayInputStream(pict.toByteArray()), "Pictures"
);
writtenEntries.add("Pictures");
}
// If requested, write out any other streams we spot
if(preserveNodes) {
copyNodes(filesystem, outFS, writtenEntries);
}
// Send the POIFSFileSystem object out to the underlying stream

View File

@ -37,9 +37,11 @@ public class TestReWrite extends TestCase {
// HSLFSlideShow primed on the test data
private HSLFSlideShow hssA;
private HSLFSlideShow hssB;
private HSLFSlideShow hssC;
// POIFS primed on the test data
private POIFSFileSystem pfsA;
private POIFSFileSystem pfsB;
private POIFSFileSystem pfsC;
public void setUp() throws Exception {
String dirname = System.getProperty("HSLF.testdata.path");
@ -53,6 +55,11 @@ public class TestReWrite extends TestCase {
FileInputStream fisB = new FileInputStream(filenameB);
pfsB = new POIFSFileSystem(fisB);
hssB = new HSLFSlideShow(pfsB);
String filenameC = dirname + "/WithMacros.ppt";
FileInputStream fisC = new FileInputStream(filenameC);
pfsC = new POIFSFileSystem(fisC);
hssC = new HSLFSlideShow(pfsC);
}
public void testWritesOutTheSame() throws Exception {
@ -85,6 +92,34 @@ public class TestReWrite extends TestCase {
assertEquals(_oData[i], _nData[i]);
}
}
public void testWithMacroStreams() throws Exception {
// Check that they're apparently the same
assertSlideShowWritesOutTheSame(hssC, pfsC);
// Currently has a Macros stream
assertNotNull( pfsC.getRoot().getEntry("Macros") );
// Write out normally, will loose the macro stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
hssC.write(baos);
POIFSFileSystem pfsNew = new POIFSFileSystem(
new ByteArrayInputStream(baos.toByteArray()) );
try {
pfsNew.getRoot().getEntry("Macros");
fail();
} catch(FileNotFoundException e) {
// Good, as expected
}
// But if we write out with nodes preserved, will be there
baos = new ByteArrayOutputStream();
hssC.write(baos, true);
pfsNew = new POIFSFileSystem(
new ByteArrayInputStream(baos.toByteArray()) );
assertNotNull( pfsNew.getRoot().getEntry("Macros") );
}
/**
* Ensure that simply opening a slideshow (usermodel) view of it