From b4e44585b64830bce36006cf3f47ecb5157caa1f Mon Sep 17 00:00:00 2001
From: Andreas Beeker
Date: Tue, 2 May 2017 23:29:19 +0000
Subject: [PATCH] HPSF: Add CopyCompare to IntegrationTests
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1793600 13f79535-47bb-0310-9956-ffa450edef68
---
.../apache/poi/hpsf/examples/CopyCompare.java | 47 +++++----
.../apache/poi/stress/HPSFFileHandler.java | 96 +++++++++++++++++--
.../poifs/eventfilesystem/POIFSReader.java | 45 +++++----
3 files changed, 144 insertions(+), 44 deletions(-)
diff --git a/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java b/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java
index f4b5ba10d0..5d27c968de 100644
--- a/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java
+++ b/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java
@@ -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.
*/
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) {
diff --git a/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java b/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java
index 1f3dc69056..77ad5ef061 100644
--- a/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java
+++ b/src/integrationtest/org/apache/poi/stress/HPSFFileHandler.java
@@ -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 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 EXCLUDES_HANDLE_FILE = unmodifiableHashSet(
+ "hpsf/Test_Humor-Generation.ppt"
+ );
+
+
+ private static final Set unmodifiableHashSet(String... a) {
+ return Collections.unmodifiableSet(new HashSet(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();
}
diff --git a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
index 633feba62d..c236c4b83b 100644
--- a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
+++ b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java
@@ -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.
+ * 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 properties,
final POIFSDocumentPath path)
- throws IOException
- {
+ throws IOException {
+ if (!properties.hasNext() && notifyEmptyDirectories) {
+ Iterator 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 listeners = registry.getListeners(path, name);