HPSF: Add CopyCompare to IntegrationTests

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1793600 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2017-05-02 23:29:19 +00:00
parent 3a56f1ab3f
commit eeb697001f
3 changed files with 144 additions and 44 deletions

View File

@ -47,6 +47,7 @@ import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.TempFile;
/**
@ -66,7 +67,7 @@ import org.apache.poi.util.TempFile;
* exactly identical. However, both POI file systems must contain the same
* files, and most of these files must be bitwise identical. Property set
* streams, however, are compared logically: they must have the same sections
* with the same attributs, and the sections must contain the same properties.
* with the same attributes, and the sections must contain the same properties.
* Details like the ordering of the properties do not matter.</p>
*/
public class CopyCompare
@ -124,6 +125,7 @@ public class CopyCompare
final POIFSReader r = new POIFSReader();
final CopyFile cf = new CopyFile(copyFileName);
r.registerListener(cf);
r.setNotifyEmptyDirectories(true);
FileInputStream fis = new FileInputStream(originalFileName);
r.read(fis);
fis.close();
@ -133,19 +135,23 @@ public class CopyCompare
/* Read all documents from the original POI file system and compare them
* with the equivalent document from the copy. */
final POIFSFileSystem opfs = new POIFSFileSystem(new File(originalFileName));
final POIFSFileSystem cpfs = new POIFSFileSystem(new File(copyFileName));
final DirectoryEntry oRoot = opfs.getRoot();
final DirectoryEntry cRoot = cpfs.getRoot();
final StringBuffer messages = new StringBuffer();
if (equal(oRoot, cRoot, messages)) {
System.out.println("Equal");
} else {
POIFSFileSystem opfs = null, cpfs = null;
try {
opfs = new POIFSFileSystem(new File(originalFileName));
cpfs = new POIFSFileSystem(new File(copyFileName));
final DirectoryEntry oRoot = opfs.getRoot();
final DirectoryEntry cRoot = cpfs.getRoot();
final StringBuffer messages = new StringBuffer();
if (equal(oRoot, cRoot, messages)) {
System.out.println("Equal");
} else {
System.out.println("Not equal: " + messages);
}
} finally {
IOUtils.closeQuietly(cpfs);
IOUtils.closeQuietly(opfs);
}
cpfs.close();
opfs.close();
}
@ -179,15 +185,12 @@ public class CopyCompare
/* Iterate over d1 and compare each entry with its counterpart in d2. */
for (final Entry e1 : d1) {
final String n1 = e1.getName();
Entry e2 = null;
try {
e2 = d2.getEntry(n1);
} catch (FileNotFoundException ex) {
msg.append("Document \"" + e1 + "\" exists, document \"" +
e2 + "\" does not.\n");
if (!d2.hasEntry(n1)) {
msg.append("Document \"" + n1 + "\" exists only in the source.\n");
equal = false;
break;
}
Entry e2 = d2.getEntry(n1);
if (e1.isDirectoryEntry() && e2.isDirectoryEntry()) {
equal = equal((DirectoryEntry) e1, (DirectoryEntry) e2, msg);
@ -320,7 +323,7 @@ public class CopyCompare
try {
/* Find out whether the current document is a property set
* stream or not. */
if (PropertySet.isPropertySetStream(stream)) {
if (stream != null && PropertySet.isPropertySetStream(stream)) {
/* Yes, the current document is a property set stream.
* Let's create a PropertySet instance from it. */
PropertySet ps = null;
@ -337,7 +340,7 @@ public class CopyCompare
} else {
/* No, the current document is not a property set stream. We
* copy it unmodified to the destination POIFS. */
copy(poiFs, event.getPath(), event.getName(), stream);
copy(poiFs, path, name, stream);
}
} catch (MarkUnsupportedException ex) {
t = ex;
@ -399,6 +402,10 @@ public class CopyCompare
final DocumentInputStream stream)
throws IOException {
final DirectoryEntry de = getPath(poiFs, path);
if (stream == null && name == null) {
// Empty directory
return;
}
final ByteArrayOutputStream out = new ByteArrayOutputStream();
int c;
while ((c = stream.read()) != -1) {

View File

@ -16,33 +16,113 @@
==================================================================== */
package org.apache.poi.stress;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.HPSFPropertiesOnlyDocument;
import org.apache.poi.hpsf.MarkUnsupportedException;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hpsf.examples.CopyCompare;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.TempFile;
import org.junit.Assume;
import org.junit.Test;
public class HPSFFileHandler extends POIFSFileHandler {
@Override
public void handleFile(InputStream stream) throws Exception {
HPSFPropertiesOnlyDocument hpsf = new HPSFPropertiesOnlyDocument(new POIFSFileSystem(stream));
assertNotNull(hpsf.getDocumentSummaryInformation());
assertNotNull(hpsf.getSummaryInformation());
private static File copyOutput = null;
static final Set<String> EXCLUDES_HANDLE_ADD = unmodifiableHashSet(
"spreadsheet/45290.xls",
"spreadsheet/46904.xls",
"spreadsheet/55982.xls",
"spreadsheet/testEXCEL_3.xls",
"spreadsheet/testEXCEL_4.xls",
"hpsf/Test_Humor-Generation.ppt"
);
static final Set<String> EXCLUDES_HANDLE_FILE = unmodifiableHashSet(
"hpsf/Test_Humor-Generation.ppt"
);
private static final Set<String> unmodifiableHashSet(String... a) {
return Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(a)));
}
@Override
public void handleFile(InputStream stream, String path) throws Exception {
Assume.assumeFalse(EXCLUDES_HANDLE_FILE.contains(path));
POIFSFileSystem poifs = new POIFSFileSystem(stream);
HPSFPropertiesOnlyDocument hpsf = new HPSFPropertiesOnlyDocument(poifs);
DocumentSummaryInformation dsi = hpsf.getDocumentSummaryInformation();
SummaryInformation si = hpsf.getSummaryInformation();
boolean hasDSI = hasPropertyStream(poifs, DocumentSummaryInformation.DEFAULT_STREAM_NAME);
boolean hasSI = hasPropertyStream(poifs, SummaryInformation.DEFAULT_STREAM_NAME);
assertEquals(hasDSI, dsi != null);
assertEquals(hasSI, si != null);
handlePOIDocument(hpsf);
}
private static boolean hasPropertyStream(POIFSFileSystem poifs, String streamName) throws IOException, MarkUnsupportedException {
DirectoryNode root = poifs.getRoot();
if (!root.hasEntry(streamName)) {
return false;
}
DocumentInputStream dis = root.createDocumentInputStream(streamName);
try {
return PropertySet.isPropertySetStream(dis);
} finally {
dis.close();;
}
}
@Override
public void handleAdditional(File file) throws Exception {
Assume.assumeFalse(EXCLUDES_HANDLE_ADD.contains(file.getParentFile().getName()+"/"+file.getName()));
if (copyOutput == null) {
copyOutput = TempFile.createTempFile("hpsfCopy", "out");
copyOutput.deleteOnExit();
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintStream psNew = new PrintStream(bos);
PrintStream ps = System.out;
try {
System.setOut(psNew);
CopyCompare.main(new String[]{file.getAbsolutePath(), copyOutput.getAbsolutePath()});
assertEquals("Equal\n", new String(bos.toByteArray(), Charset.forName("UTF-8")));
} finally {
System.setOut(ps);
}
}
// a test-case to test this locally without executing the full TestAllFiles
@Override
@Test
public void test() throws Exception {
InputStream stream = new FileInputStream("test-data/hpsf/Test0313rur.adm");
String path = "test-data/hpsf/Test0313rur.adm";
InputStream stream = new FileInputStream(path);
try {
handleFile(stream);
handleFile(stream, path);
} finally {
stream.close();
}

View File

@ -51,6 +51,7 @@ public class POIFSReader
{
private final POIFSReaderRegistry registry;
private boolean registryClosed;
private boolean notifyEmptyDirectories = false;
/**
* Create a POIFSReader
@ -180,6 +181,18 @@ public class POIFSReader
: path, name);
}
/**
* Activates the notification of empty directories.<p>
* If this flag is activated, the {@link POIFSReaderListener listener} receives
* {@link POIFSReaderEvent POIFSReaderEvents} with nulled {@code name} and {@code stream}
*
* @param notifyEmptyDirectories
*/
public void setNotifyEmptyDirectories(boolean notifyEmptyDirectories) {
this.notifyEmptyDirectories = notifyEmptyDirectories;
}
/**
* read in files
*
@ -216,27 +229,27 @@ public class POIFSReader
final BlockList big_blocks,
final Iterator<Property> properties,
final POIFSDocumentPath path)
throws IOException
{
throws IOException {
if (!properties.hasNext() && notifyEmptyDirectories) {
Iterator<POIFSReaderListener> listeners = registry.getListeners(path, ".");
while (listeners.hasNext()) {
POIFSReaderListener pl = listeners.next();
POIFSReaderEvent pe = new POIFSReaderEvent(null, path, null);
pl.processPOIFSReaderEvent(pe);
}
return;
}
while (properties.hasNext())
{
Property property = properties.next();
String name = property.getName();
if (property.isDirectory())
{
POIFSDocumentPath new_path = new POIFSDocumentPath(path,
new String[]
{
name
});
processProperties(
small_blocks, big_blocks,
(( DirectoryProperty ) property).getChildren(), new_path);
}
else
{
if (property.isDirectory()) {
POIFSDocumentPath new_path = new POIFSDocumentPath(path,new String[]{name});
DirectoryProperty dp = (DirectoryProperty) property;
processProperties(small_blocks, big_blocks, dp.getChildren(), new_path);
} else {
int startBlock = property.getStartBlock();
Iterator<POIFSReaderListener> listeners = registry.getListeners(path, name);