FileDocCategorySizeDatePackage
CopyCompare.javaAPI DocApache Poi 3.0.121775Mon Jan 01 12:39:42 GMT 2007org.apache.poi.hpsf.examples

CopyCompare

public class CopyCompare extends Object

This class copies a POI file system to a new file and compares the copy with the original.

Property set streams are copied logically, i.e. the application establishes a {@link org.apache.poi.hpsf.PropertySet} of an original property set, creates a {@link org.apache.poi.hpsf.MutablePropertySet} from the {@link org.apache.poi.hpsf.PropertySet} and writes the {@link org.apache.poi.hpsf.MutablePropertySet} to the destination POI file system. - Streams which are no property set streams are copied bit by bit.

The comparison of the POI file systems is done logically. That means that the two disk files containing the POI file systems do not need to be 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. Details like the ordering of the properties do not matter.

author
Rainer Klute <klute@rainer-klute.de>
version
$Id: CopyCompare.java 489730 2006-12-22 19:18:16Z bayard $
since
2003-09-19

Fields Summary
Constructors Summary
Methods Summary
private static booleanequal(org.apache.poi.poifs.filesystem.DirectoryEntry d1, org.apache.poi.poifs.filesystem.DirectoryEntry d2, java.lang.StringBuffer msg)

Compares two {@link DirectoryEntry} instances of a POI file system. The directories must contain the same streams with the same names and contents.

param
d1 The first directory.
param
d2 The second directory.
param
msg The method may append human-readable comparison messages to this string buffer.
return
true if the directories are equal, else false.
exception
MarkUnsupportedException if a POI document stream does not support the mark() operation.
exception
NoPropertySetStreamException if the application tries to create a property set from a POI document stream that is not a property set stream.
throws
UnsupportedEncodingException
exception
IOException if any I/O exception occurs.

        boolean equal = true;
        /* Iterate over d1 and compare each entry with its counterpart in d2. */
        for (final Iterator i = d1.getEntries(); equal && i.hasNext();)
        {
            final Entry e1 = (Entry) i.next();
            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");
                equal = false;
                break;
            }

            if (e1.isDirectoryEntry() && e2.isDirectoryEntry())
                equal = equal((DirectoryEntry) e1, (DirectoryEntry) e2, msg);
            else if (e1.isDocumentEntry() && e2.isDocumentEntry())
                equal = equal((DocumentEntry) e1, (DocumentEntry) e2, msg);
            else
            {
                msg.append("One of \"" + e1 + "\" and \"" + e2 + "\" is a " +
                           "document while the other one is a directory.\n");
                equal = false;
            }
        }

        /* Iterate over d2 just to make sure that there are no entries in d2
         * that are not in d1. */
        for (final Iterator i = d2.getEntries(); equal && i.hasNext();)
        {
            final Entry e2 = (Entry) i.next();
            final String n2 = e2.getName();
            Entry e1 = null;
            try
            {
                e1 = d1.getEntry(n2);
            }
            catch (FileNotFoundException ex)
            {
                msg.append("Document \"" + e2 + "\" exitsts, document \"" +
                           e1 + "\" does not.\n");
                equal = false;
                break;
            }
        }
        return equal;
    
private static booleanequal(org.apache.poi.poifs.filesystem.DocumentEntry d1, org.apache.poi.poifs.filesystem.DocumentEntry d2, java.lang.StringBuffer msg)

Compares two {@link DocumentEntry} instances of a POI file system. Documents that are not property set streams must be bitwise identical. Property set streams must be logically equal.

param
d1 The first document.
param
d2 The second document.
param
msg The method may append human-readable comparison messages to this string buffer.
return
true if the documents are equal, else false.
exception
MarkUnsupportedException if a POI document stream does not support the mark() operation.
exception
NoPropertySetStreamException if the application tries to create a property set from a POI document stream that is not a property set stream.
throws
UnsupportedEncodingException
exception
IOException if any I/O exception occurs.

        boolean equal = true;
        final DocumentInputStream dis1 = new DocumentInputStream(d1);
        final DocumentInputStream dis2 = new DocumentInputStream(d2);
        if (PropertySet.isPropertySetStream(dis1) &&
            PropertySet.isPropertySetStream(dis2))
        {
            final PropertySet ps1 = PropertySetFactory.create(dis1);
            final PropertySet ps2 = PropertySetFactory.create(dis2);
            equal = ps1.equals(ps2);
            if (!equal)
            {
                msg.append("Property sets are not equal.\n");
                return equal;
            }
        }
        else
        {
            int i1;
            int i2;
            do
            {
                i1 = dis1.read();
                i2 = dis2.read();
                if (i1 != i2)
                {
                    equal = false;
                    msg.append("Documents are not equal.\n");
                    break;
                }
            }
            while (equal && i1 == -1);
        }
        return true;
    
public static voidmain(java.lang.String[] args)

Runs the example program. The application expects one or two arguments:

  1. The first argument is the disk file name of the POI filesystem to copy.

  2. The second argument is optional. If it is given, it is the name of a disk file the copy of the POI filesystem will be written to. If it is not given, the copy will be written to a temporary file which will be deleted at the end of the program.

param
args Command-line arguments.
exception
MarkUnsupportedException if a POI document stream does not support the mark() operation.
exception
NoPropertySetStreamException if the application tries to create a property set from a POI document stream that is not a property set stream.
exception
IOException if any I/O exception occurs.
exception
UnsupportedEncodingException if a character encoding is not supported.

        String originalFileName = null;
        String copyFileName = null;

        /* Check the command-line arguments. */
        if (args.length == 1)
        {
            originalFileName = args[0];
            File f = TempFile.createTempFile("CopyOfPOIFileSystem-", ".ole2");
            f.deleteOnExit();
            copyFileName = f.getAbsolutePath();
        }
        else if (args.length == 2)
        {
            originalFileName = args[0];
            copyFileName = args[1];
        }
        else
        {
            System.err.println("Usage: " + CopyCompare.class.getName() +
                               "originPOIFS [copyPOIFS]");
            System.exit(1);
        }

        /* Read the origin POIFS using the eventing API. The real work is done
         * in the class CopyFile which is registered here as a POIFSReader. */
        final POIFSReader r = new POIFSReader();
        final CopyFile cf = new CopyFile(copyFileName);
        r.registerListener(cf);
        r.read(new FileInputStream(originalFileName));
        
        /* Write the new POIFS to disk. */
        cf.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 FileInputStream(originalFileName));
        final POIFSFileSystem cpfs =
            new POIFSFileSystem(new FileInputStream(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.toString());