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:
parent
312b7ff2dc
commit
ed2d78b08b
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
BIN
src/scratchpad/testcases/org/apache/poi/hslf/data/WithMacros.ppt
Normal file
BIN
src/scratchpad/testcases/org/apache/poi/hslf/data/WithMacros.ppt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user