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;
/**
* 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
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();
/* 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();
}
/* 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);
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;
} 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;
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) {
==================================================================== */
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();
}
{
private final POIFSReaderRegistry registry;
private boolean registryClosed;
+ private boolean notifyEmptyDirectories = false;
/**
* Create a 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
*
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);