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.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.hpsf.DocumentSummaryInformation;
|
import org.apache.poi.hpsf.DocumentSummaryInformation;
|
||||||
import org.apache.poi.hpsf.MutablePropertySet;
|
import org.apache.poi.hpsf.MutablePropertySet;
|
||||||
import org.apache.poi.hpsf.PropertySet;
|
import org.apache.poi.hpsf.PropertySet;
|
||||||
import org.apache.poi.hpsf.PropertySetFactory;
|
import org.apache.poi.hpsf.PropertySetFactory;
|
||||||
import org.apache.poi.hpsf.SummaryInformation;
|
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.DocumentInputStream;
|
||||||
|
import org.apache.poi.poifs.filesystem.Entry;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
@ -106,11 +111,25 @@ public abstract class POIDocument {
|
|||||||
* @param outFS the POIFSFileSystem to write the properties into
|
* @param outFS the POIFSFileSystem to write the properties into
|
||||||
*/
|
*/
|
||||||
protected void writeProperties(POIFSFileSystem outFS) throws IOException {
|
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) {
|
if(sInf != null) {
|
||||||
writePropertySet(SummaryInformation.DEFAULT_STREAM_NAME,sInf,outFS);
|
writePropertySet(SummaryInformation.DEFAULT_STREAM_NAME,sInf,outFS);
|
||||||
|
if(writtenEntries != null) {
|
||||||
|
writtenEntries.add(SummaryInformation.DEFAULT_STREAM_NAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(dsInf != null) {
|
if(dsInf != null) {
|
||||||
writePropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME,dsInf,outFS);
|
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");
|
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
|
// Get a new Filesystem to write into
|
||||||
POIFSFileSystem outFS = new POIFSFileSystem();
|
POIFSFileSystem outFS = new POIFSFileSystem();
|
||||||
|
|
||||||
|
// The list of entries we've written out
|
||||||
|
List writtenEntries = new ArrayList(1);
|
||||||
|
|
||||||
// Write out the Property Streams
|
// Write out the Property Streams
|
||||||
writeProperties(outFS);
|
writeProperties(outFS, writtenEntries);
|
||||||
|
|
||||||
|
|
||||||
// For position dependent records, hold where they were and now are
|
// 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
|
// Write the PPT stream into the POIFS layer
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||||
outFS.createDocument(bais,"PowerPoint Document");
|
outFS.createDocument(bais,"PowerPoint Document");
|
||||||
|
writtenEntries.add("PowerPoint Document");
|
||||||
|
|
||||||
|
|
||||||
// Update and write out the Current User atom
|
// Update and write out the Current User atom
|
||||||
@ -445,6 +449,7 @@ public class HSLFSlideShow extends POIDocument
|
|||||||
}
|
}
|
||||||
currentUser.setCurrentEditOffset(newLastUserEditAtomPos.intValue());
|
currentUser.setCurrentEditOffset(newLastUserEditAtomPos.intValue());
|
||||||
currentUser.writeToFS(outFS);
|
currentUser.writeToFS(outFS);
|
||||||
|
writtenEntries.add("Current User");
|
||||||
|
|
||||||
|
|
||||||
// Write any pictures, into another stream
|
// Write any pictures, into another stream
|
||||||
@ -456,6 +461,12 @@ public class HSLFSlideShow extends POIDocument
|
|||||||
outFS.createDocument(
|
outFS.createDocument(
|
||||||
new ByteArrayInputStream(pict.toByteArray()), "Pictures"
|
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
|
// Send the POIFSFileSystem object out to the underlying stream
|
||||||
|
@ -37,9 +37,11 @@ public class TestReWrite extends TestCase {
|
|||||||
// HSLFSlideShow primed on the test data
|
// HSLFSlideShow primed on the test data
|
||||||
private HSLFSlideShow hssA;
|
private HSLFSlideShow hssA;
|
||||||
private HSLFSlideShow hssB;
|
private HSLFSlideShow hssB;
|
||||||
|
private HSLFSlideShow hssC;
|
||||||
// POIFS primed on the test data
|
// POIFS primed on the test data
|
||||||
private POIFSFileSystem pfsA;
|
private POIFSFileSystem pfsA;
|
||||||
private POIFSFileSystem pfsB;
|
private POIFSFileSystem pfsB;
|
||||||
|
private POIFSFileSystem pfsC;
|
||||||
|
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
String dirname = System.getProperty("HSLF.testdata.path");
|
String dirname = System.getProperty("HSLF.testdata.path");
|
||||||
@ -53,6 +55,11 @@ public class TestReWrite extends TestCase {
|
|||||||
FileInputStream fisB = new FileInputStream(filenameB);
|
FileInputStream fisB = new FileInputStream(filenameB);
|
||||||
pfsB = new POIFSFileSystem(fisB);
|
pfsB = new POIFSFileSystem(fisB);
|
||||||
hssB = new HSLFSlideShow(pfsB);
|
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 {
|
public void testWritesOutTheSame() throws Exception {
|
||||||
@ -85,6 +92,34 @@ public class TestReWrite extends TestCase {
|
|||||||
assertEquals(_oData[i], _nData[i]);
|
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
|
* 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