FileDocCategorySizeDatePackage
TestWrite.javaAPI DocApache Poi 3.0.133579Mon Jan 01 12:39:44 GMT 2007org.apache.poi.hpsf.basic

TestWrite

public class TestWrite extends TestCase

Tests HPSF's writing functionality.

author
Rainer Klute (klute@rainer-klute.de)
since
2003-02-07
version
$Id: TestWrite.java 489730 2006-12-22 19:18:16Z bayard $

Fields Summary
static final String
POI_FS
static final int
BYTE_ORDER
static final int
FORMAT
static final int
OS_VERSION
static final int[]
SECTION_COUNT
static final boolean[]
IS_SUMMARY_INFORMATION
static final boolean[]
IS_DOCUMENT_SUMMARY_INFORMATION
final String
IMPROPER_DEFAULT_CHARSET_MESSAGE
POIFile[]
poiFiles
private static final int
CODEPAGE_DEFAULT
private static final int
CODEPAGE_1252
private static final int
CODEPAGE_UTF8
private static final int
CODEPAGE_UTF16
Constructors Summary
public TestWrite(String name)

Constructor

param
name the test case's name




                 
       
    
        super(name);
    
Methods Summary
private voidcheck(long variantType, java.lang.Object value, int codepage)

Writes a property and reads it back in.

param
variantType The property's variant type.
param
value The property's value.
param
codepage The codepage to use for writing and reading.
throws
UnsupportedVariantTypeException if the variant is not supported.
throws
IOException if an I/O exception occurs.
throws
ReadingNotSupportedException
throws
UnsupportedEncodingException

        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        VariantSupport.write(out, variantType, value, codepage);
        out.close();
        final byte[] b = out.toByteArray();
        final Object objRead =
            VariantSupport.read(b, 0, b.length + LittleEndian.INT_SIZE,
                                variantType, codepage);
        if (objRead instanceof byte[])
        {
            final int diff = diff((byte[]) value, (byte[]) objRead);
            if (diff >= 0)
                fail("Byte arrays are different. First different byte is at " +
                     "index " + diff + ".");
        }
        else
            if (value != null && !value.equals(objRead))
            {
                fail("Expected: \"" + value + "\" but was: \"" + objRead +
                     "\". Codepage: " + codepage +
                     (codepage == -1 ?
                      " (" + System.getProperty("file.encoding") + ")." : "."));
            }
            else
                assertEquals(value, objRead);
    
private intdiff(byte[] a, byte[] b)

Compares two byte arrays.

param
a The first byte array
param
b The second byte array
return
The index of the first byte that is different. If the byte arrays are equal, -1 is returned.

        final int min = Math.min(a.length, b.length);
        for (int i = 0; i < min; i++)
            if (a[i] != b[i])
                return i;
        if (a.length != b.length)
            return min;
        return -1;
    
private java.lang.StringgetDefaultCharsetName()

Returns the display name of the default character set.

return
the display name of the default character set.

        final String charSetName = System.getProperty("file.encoding");
        final Charset charSet = Charset.forName(charSetName);
        return charSet.displayName();
    
private voidhandle(java.lang.Exception ex)

Handles unexpected exceptions in testcases.

param
ex The exception that has been thrown.

        final StringWriter sw = new StringWriter();
        final PrintWriter pw = new PrintWriter(sw);
        Throwable t = ex;
        while (t != null)
        {
            t.printStackTrace(pw);
            if (t instanceof HPSFRuntimeException)
                t = ((HPSFRuntimeException) t).getReason();
            else
                t = null;
            if (t != null)
                pw.println("Caused by:");
        }
        pw.close();
        try
        {
            sw.close();
        }
        catch (IOException ex2)
        {
            ex.printStackTrace();
        }
        fail(sw.toString());
    
private booleanhasProperDefaultCharset()

In order to execute tests with characters beyond US-ASCII, this method checks whether the application is runing in an environment where the default character set is 16-bit-capable.

return
true if the default character set is 16-bit-capable, else false.

        final String charSetName = System.getProperty("file.encoding");
        final Charset charSet = Charset.forName(charSetName);
        return charSet.newEncoder().canEncode('\u00e4");
    
public static voidmain(java.lang.String[] args)

Runs the test cases stand-alone.

param
args The command-line parameters.
throws
Throwable if anything goes wrong.

        System.setProperty("HPSF.testdata.path",
                           "./src/testcases/org/apache/poi/hpsf/data");
        junit.textui.TestRunner.run(TestWrite.class);
    
public voidsetUp()

see
TestCase#setUp()

        VariantSupport.setLogUnsupportedTypes(false);
    
public voidtestCodepages()

Writes and reads back strings using several different codepages and checks whether the stuff that has been read back equals the stuff that was written.

        Throwable thr = null;
        final int[] validCodepages = new int[]
            {CODEPAGE_DEFAULT, CODEPAGE_UTF8, CODEPAGE_UTF16, CODEPAGE_1252};
        for (int i = 0; i < validCodepages.length; i++)
        {
            final int cp = validCodepages[i];
            if (cp == -1 && !hasProperDefaultCharset())            
            {
                System.err.println(IMPROPER_DEFAULT_CHARSET_MESSAGE +
                     " This testcase is skipped for the default codepage.");
                continue;
            }

            final long t = cp == CODEPAGE_UTF16 ? Variant.VT_LPWSTR
                                                : Variant.VT_LPSTR;
            try
            {
                check(t, "", cp);
                check(t, "\u00e4", cp);
                check(t, "\u00e4\u00f6", cp);
                check(t, "\u00e4\u00f6\u00fc", cp);
                check(t, "\u00e4\u00f6\u00fc\u00c4", cp);
                check(t, "\u00e4\u00f6\u00fc\u00c4\u00d6", cp);
                check(t, "\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc", cp);
                check(t, "\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc\u00df", cp);
                if (cp == Constants.CP_UTF16 || cp == Constants.CP_UTF8)
                    check(t, "\u79D1\u5B78", cp);
            }
            catch (Exception ex)
            {
                thr = ex;
            }
            catch (Error ex)
            {
                thr = ex;
            }
            if (thr != null)
                fail(org.apache.poi.hpsf.Util.toString(thr) +
                     " with codepage " + cp);
        }

        final int[] invalidCodepages = new int[] {0, 1, 2, 4711, 815};
        for (int i = 0; i < invalidCodepages.length; i++)
        {
            int cp = invalidCodepages[i];
            final long type = cp == CODEPAGE_UTF16 ? Variant.VT_LPWSTR
                                                   : Variant.VT_LPSTR;
            try
            {
                check(type, "", cp);
                check(type, "\u00e4", cp);
                check(type, "\u00e4\u00f6", cp);
                check(type, "\u00e4\u00f6\u00fc", cp);
                check(type, "\u00e4\u00f6\u00fc\u00c4", cp);
                check(type, "\u00e4\u00f6\u00fc\u00c4\u00d6", cp);
                check(type, "\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc", cp);
                check(type, "\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc\u00df", cp);
                fail("UnsupportedEncodingException for codepage " + cp +
                     " expected.");
            }
            catch (UnsupportedEncodingException ex)
            {
                /* This is the expected behaviour. */
            }
            catch (Exception ex)
            {
                thr = ex;
            }
            catch (Error ex)
            {
                thr = ex;
            }
            if (thr != null)
                fail(org.apache.poi.hpsf.Util.toString(thr));
        }

    
public voidtestDictionary()

Tests writing and reading back a proper dictionary.

        try
        {
            final File copy = TempFile.createTempFile("Test-HPSF", "ole2");
            copy.deleteOnExit();

            /* Write: */
            final OutputStream out = new FileOutputStream(copy);
            final POIFSFileSystem poiFs = new POIFSFileSystem();
            final MutablePropertySet ps1 = new MutablePropertySet();
            final MutableSection s = (MutableSection) ps1.getSections().get(0);
            final Map m = new HashMap(3, 1.0f);
            m.put(new Long(1), "String 1");
            m.put(new Long(2), "String 2");
            m.put(new Long(3), "String 3");
            s.setDictionary(m);
            s.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]);
            int codepage = Constants.CP_UNICODE;
            s.setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2,
                          new Integer(codepage));
            poiFs.createDocument(ps1.toInputStream(), "Test");
            poiFs.writeFilesystem(out);
            out.close();

            /* Read back: */
            final POIFile[] psf = Util.readPropertySets(copy);
            Assert.assertEquals(1, psf.length);
            final byte[] bytes = psf[0].getBytes();
            final InputStream in = new ByteArrayInputStream(bytes);
            final PropertySet ps2 = PropertySetFactory.create(in);

            /* Check if the result is a DocumentSummaryInformation stream, as
             * specified. */
            assertTrue(ps2.isDocumentSummaryInformation());

            /* Compare the property set stream with the corresponding one
             * from the origin file and check whether they are equal. */
            assertEquals(ps1, ps2);
        }
        catch (Exception ex)
        {
            handle(ex);
        }
    
public voidtestDictionaryWithInvalidCodepage()

Tests writing and reading back a proper dictionary with an invalid codepage. (HPSF writes Unicode dictionaries only.)

        try
        {
            final File copy = TempFile.createTempFile("Test-HPSF", "ole2");
            copy.deleteOnExit();

            /* Write: */
            final OutputStream out = new FileOutputStream(copy);
            final POIFSFileSystem poiFs = new POIFSFileSystem();
            final MutablePropertySet ps1 = new MutablePropertySet();
            final MutableSection s = (MutableSection) ps1.getSections().get(0);
            final Map m = new HashMap(3, 1.0f);
            m.put(new Long(1), "String 1");
            m.put(new Long(2), "String 2");
            m.put(new Long(3), "String 3");
            s.setDictionary(m);
            s.setFormatID(SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID[0]);
            int codepage = 12345;
            s.setProperty(PropertyIDMap.PID_CODEPAGE, Variant.VT_I2,
                          new Integer(codepage));
            poiFs.createDocument(ps1.toInputStream(), "Test");
            poiFs.writeFilesystem(out);
            out.close();
            fail("This testcase did not detect the invalid codepage value.");
        }
        catch (IllegalPropertySetDataException ex)
        {
            assertTrue(true);
        }
        catch (Exception ex)
        {
            handle(ex);
        }
    
public voidtestNoFormatID()

Writes an empty property set to a POIFS and reads it back in.

exception
IOException if an I/O exception occurs

        final String dataDirName = System.getProperty("HPSF.testdata.path");
        final File dataDir = new File(dataDirName);
        final File filename = new File(dataDir, POI_FS);
        filename.deleteOnExit();

        /* Create a mutable property set with a section that does not have the
         * formatID set: */
        final OutputStream out = new FileOutputStream(filename);
        final POIFSFileSystem poiFs = new POIFSFileSystem();
        final MutablePropertySet ps = new MutablePropertySet();
        ps.clearSections();
        ps.addSection(new MutableSection());

        /* Write it to a POIFS and the latter to disk: */
        try
        {
            final ByteArrayOutputStream psStream = new ByteArrayOutputStream();
            ps.write(psStream);
            psStream.close();
            final byte[] streamData = psStream.toByteArray();
            poiFs.createDocument(new ByteArrayInputStream(streamData),
                                 SummaryInformation.DEFAULT_STREAM_NAME);
            poiFs.writeFilesystem(out);
            out.close();
            Assert.fail("Should have thrown a NoFormatIDException.");
        }
        catch (Exception ex)
        {
            Assert.assertTrue(ex instanceof NoFormatIDException);
        }
        finally
        {
            out.close();
        }
    
public voidtestRecreate()

This test method does a write and read back test with all POI filesystems in the "data" directory by performing the following actions for each file:

  • Read its property set streams.

  • Create a new POI filesystem containing the origin file's property set streams.

  • Read the property set streams from the POI filesystem just created.

  • Compare each property set stream with the corresponding one from the origin file and check whether they are equal.

        final File dataDir =
            new File(System.getProperty("HPSF.testdata.path"));
        final File[] fileList = dataDir.listFiles(new FileFilter()
            {
                public boolean accept(final File f)
                {
                    return f.getName().startsWith("Test");
                }
            });
        for (int i = 0; i < fileList.length; i++)
            testRecreate(fileList[i]);
    
private voidtestRecreate(java.io.File f)

Performs the check described in {@link #testRecreate()} for a single POI filesystem.

param
f the POI filesystem to check

        System.out.println("Recreating file \"" + f + "\"");
        try
        {
            /* Read the POI filesystem's property set streams: */
            final POIFile[] psf1 = Util.readPropertySets(f);

            /* Create a new POI filesystem containing the origin file's
             * property set streams: */
            final File copy = TempFile.createTempFile(f.getName(), "");
            copy.deleteOnExit();
            final OutputStream out = new FileOutputStream(copy);
            final POIFSFileSystem poiFs = new POIFSFileSystem();
            for (int i = 0; i < psf1.length; i++)
            {
                final InputStream in =
                    new ByteArrayInputStream(psf1[i].getBytes());
                final PropertySet psIn = PropertySetFactory.create(in);
                final MutablePropertySet psOut = new MutablePropertySet(psIn);
                final ByteArrayOutputStream psStream =
                    new ByteArrayOutputStream();
                psOut.write(psStream);
                psStream.close();
                final byte[] streamData = psStream.toByteArray();
                poiFs.createDocument(new ByteArrayInputStream(streamData),
                                     psf1[i].getName());
                poiFs.writeFilesystem(out);
            }
            out.close();


            /* Read the property set streams from the POI filesystem just
             * created. */
            final POIFile[] psf2 = Util.readPropertySets(copy);
            for (int i = 0; i < psf2.length; i++)
            {
                final byte[] bytes1 = psf1[i].getBytes();
                final byte[] bytes2 = psf2[i].getBytes();
                final InputStream in1 = new ByteArrayInputStream(bytes1);
                final InputStream in2 = new ByteArrayInputStream(bytes2);
                final PropertySet ps1 = PropertySetFactory.create(in1);
                final PropertySet ps2 = PropertySetFactory.create(in2);
            
                /* Compare the property set stream with the corresponding one
                 * from the origin file and check whether they are equal. */
                assertEquals("Equality for file " + f.getName(), ps1, ps2);
            }
        }
        catch (Exception ex)
        {
            handle(ex);
        }
    
public voidtestUnicodeWrite8Bit()

Tests whether writing 8-bit characters to a Unicode property succeeds.

        final String TITLE = "This is a sample title";
        final MutablePropertySet mps = new MutablePropertySet();
        final MutableSection ms = (MutableSection) mps.getSections().get(0);
        ms.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID);
        final MutableProperty p = new MutableProperty();
        p.setID(PropertyIDMap.PID_TITLE);
        p.setType(Variant.VT_LPSTR);
        p.setValue(TITLE);
        ms.setProperty(p);

        Throwable t = null;
        try
        {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            mps.write(out);
            out.close();
            byte[] bytes = out.toByteArray();

            PropertySet psr = new PropertySet(bytes);
            assertTrue(psr.isSummaryInformation());
            Section sr = (Section) psr.getSections().get(0);
            String title = (String) sr.getProperty(PropertyIDMap.PID_TITLE);
            assertEquals(TITLE, title);
        }
        catch (WritingNotSupportedException e)
        {
            t = e;
        }
        catch (IOException e)
        {
            t = e;
        }
        catch (NoPropertySetStreamException e)
        {
            t = e;
        }
        if (t != null)
            fail(t.getMessage());
    
public voidtestVariantTypes()

Writes and reads back various variant types and checks whether the stuff that has been read back equals the stuff that was written.




                                
      
    
        Throwable t = null;
        final int codepage = CODEPAGE_DEFAULT;
        if (!hasProperDefaultCharset())            
        {
            System.err.println(IMPROPER_DEFAULT_CHARSET_MESSAGE +
                " This testcase is skipped.");
            return;
        }

        try
        {
            check(Variant.VT_EMPTY, null, codepage);
            check(Variant.VT_BOOL, new Boolean(true), codepage);
            check(Variant.VT_BOOL, new Boolean(false), codepage);
            check(Variant.VT_CF, new byte[]{0}, codepage);
            check(Variant.VT_CF, new byte[]{0, 1}, codepage);
            check(Variant.VT_CF, new byte[]{0, 1, 2}, codepage);
            check(Variant.VT_CF, new byte[]{0, 1, 2, 3}, codepage);
            check(Variant.VT_CF, new byte[]{0, 1, 2, 3, 4}, codepage);
            check(Variant.VT_CF, new byte[]{0, 1, 2, 3, 4, 5}, codepage);
            check(Variant.VT_CF, new byte[]{0, 1, 2, 3, 4, 5, 6}, codepage);
            check(Variant.VT_CF, new byte[]{0, 1, 2, 3, 4, 5, 6, 7}, codepage);
            check(Variant.VT_I4, new Integer(27), codepage);
            check(Variant.VT_I8, new Long(28), codepage);
            check(Variant.VT_R8, new Double(29.0), codepage);
            check(Variant.VT_I4, new Integer(-27), codepage);
            check(Variant.VT_I8, new Long(-28), codepage);
            check(Variant.VT_R8, new Double(-29.0), codepage);
            check(Variant.VT_FILETIME, new Date(), codepage);
            check(Variant.VT_I4, new Integer(Integer.MAX_VALUE), codepage);
            check(Variant.VT_I4, new Integer(Integer.MIN_VALUE), codepage);
            check(Variant.VT_I8, new Long(Long.MAX_VALUE), codepage);
            check(Variant.VT_I8, new Long(Long.MIN_VALUE), codepage);
            check(Variant.VT_R8, new Double(Double.MAX_VALUE), codepage);
            check(Variant.VT_R8, new Double(Double.MIN_VALUE), codepage);

            check(Variant.VT_LPSTR,
                  "", codepage);
            check(Variant.VT_LPSTR,
                  "\u00e4", codepage);
            check(Variant.VT_LPSTR,
                  "\u00e4\u00f6", codepage);
            check(Variant.VT_LPSTR,
                  "\u00e4\u00f6\u00fc", codepage);
            check(Variant.VT_LPSTR,
                  "\u00e4\u00f6\u00fc\u00df", codepage);
            check(Variant.VT_LPSTR,
                  "\u00e4\u00f6\u00fc\u00df\u00c4", codepage);
            check(Variant.VT_LPSTR,
                  "\u00e4\u00f6\u00fc\u00df\u00c4\u00d6", codepage);
            check(Variant.VT_LPSTR,
                  "\u00e4\u00f6\u00fc\u00df\u00c4\u00d6\u00dc", codepage);

            check(Variant.VT_LPWSTR,
                  "", codepage);
            check(Variant.VT_LPWSTR,
                  "\u00e4", codepage);
            check(Variant.VT_LPWSTR,
                  "\u00e4\u00f6", codepage);
            check(Variant.VT_LPWSTR,
                  "\u00e4\u00f6\u00fc", codepage);
            check(Variant.VT_LPWSTR,
                  "\u00e4\u00f6\u00fc\u00df", codepage);
            check(Variant.VT_LPWSTR,
                  "\u00e4\u00f6\u00fc\u00df\u00c4", codepage);
            check(Variant.VT_LPWSTR,
                  "\u00e4\u00f6\u00fc\u00df\u00c4\u00d6", codepage);
            check(Variant.VT_LPWSTR,
                  "\u00e4\u00f6\u00fc\u00df\u00c4\u00d6\u00dc", codepage);
        }
        catch (Exception ex)
        {
            t = ex;
        }
        catch (Error ex)
        {
            t = ex;
        }
        if (t != null)
            fail(org.apache.poi.hpsf.Util.toString(t));
    
public voidtestWriteEmptyPropertySet()

Writes an empty property set to a POIFS and reads it back in.

exception
IOException if an I/O exception occurs
exception
UnsupportedVariantTypeException if HPSF does not yet support a variant type to be written

        final File dataDir =
            new File(System.getProperty("HPSF.testdata.path"));
        final File filename = new File(dataDir, POI_FS);
        filename.deleteOnExit();

        /* Create a mutable property set and write it to a POIFS: */
        final OutputStream out = new FileOutputStream(filename);
        final POIFSFileSystem poiFs = new POIFSFileSystem();
        final MutablePropertySet ps = new MutablePropertySet();
        final MutableSection s = (MutableSection) ps.getSections().get(0);
        s.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID);

        final ByteArrayOutputStream psStream = new ByteArrayOutputStream();
        ps.write(psStream);
        psStream.close();
        final byte[] streamData = psStream.toByteArray();
        poiFs.createDocument(new ByteArrayInputStream(streamData),
                             SummaryInformation.DEFAULT_STREAM_NAME);
        poiFs.writeFilesystem(out);
        out.close();

        /* Read the POIFS: */
        final POIFSReader r = new POIFSReader();
        r.registerListener(new MyPOIFSReaderListener(),
                           SummaryInformation.DEFAULT_STREAM_NAME);
        r.read(new FileInputStream(filename));
    
public voidtestWriteSimplePropertySet()

Writes a simple property set with a SummaryInformation section to a POIFS and reads it back in.

exception
IOException if an I/O exception occurs
exception
UnsupportedVariantTypeException if HPSF does not yet support a variant type to be written

        final String AUTHOR = "Rainer Klute";
        final String TITLE = "Test Document"; 
        final File dataDir =
            new File(System.getProperty("HPSF.testdata.path"));
        final File filename = new File(dataDir, POI_FS);
        filename.deleteOnExit();
        final OutputStream out = new FileOutputStream(filename);
        final POIFSFileSystem poiFs = new POIFSFileSystem();
    
        final MutablePropertySet ps = new MutablePropertySet();
        final MutableSection si = new MutableSection();
        si.setFormatID(SectionIDMap.SUMMARY_INFORMATION_ID);
        ps.getSections().set(0, si);
    
        final MutableProperty p = new MutableProperty();
        p.setID(PropertyIDMap.PID_AUTHOR);
        p.setType(Variant.VT_LPWSTR);
        p.setValue(AUTHOR);
        si.setProperty(p);
        si.setProperty(PropertyIDMap.PID_TITLE, Variant.VT_LPSTR, TITLE);
    
        poiFs.createDocument(ps.toInputStream(),
                             SummaryInformation.DEFAULT_STREAM_NAME);
        poiFs.writeFilesystem(out);
        out.close();
    
        /* Read the POIFS: */
        final PropertySet[] psa = new PropertySet[1];
        final POIFSReader r = new POIFSReader();
        r.registerListener(new POIFSReaderListener()
            {
                public void processPOIFSReaderEvent
                    (final POIFSReaderEvent event)
                {
                    try
                    {
                        psa[0] = PropertySetFactory.create(event.getStream());
                    }
                    catch (Exception ex)
                    {
                        fail(org.apache.poi.hpsf.Util.toString(ex));
                    }
                }
    
            },
            SummaryInformation.DEFAULT_STREAM_NAME);
        r.read(new FileInputStream(filename));
        Assert.assertNotNull(psa[0]);
        Assert.assertTrue(psa[0].isSummaryInformation());

        final Section s = (Section) (psa[0].getSections().get(0));
        Object p1 = s.getProperty(PropertyIDMap.PID_AUTHOR);
        Object p2 = s.getProperty(PropertyIDMap.PID_TITLE);
        Assert.assertEquals(AUTHOR, p1);
        Assert.assertEquals(TITLE, p2);
    
public voidtestWriteTwoSections()

Writes a simple property set with two sections to a POIFS and reads it back in.

exception
IOException if an I/O exception occurs
exception
WritingNotSupportedException if HPSF does not yet support a variant type to be written

        final String STREAM_NAME = "PropertySetStream";
        final String SECTION1 = "Section 1";
        final String SECTION2 = "Section 2";

        final File dataDir =
            new File(System.getProperty("HPSF.testdata.path"));
        final File filename = new File(dataDir, POI_FS);
        filename.deleteOnExit();
        final OutputStream out = new FileOutputStream(filename);

        final POIFSFileSystem poiFs = new POIFSFileSystem();
        final MutablePropertySet ps = new MutablePropertySet();
        ps.clearSections();

        final ClassID formatID = new ClassID();
        formatID.setBytes(new byte[]{0, 1,  2,  3,  4,  5,  6,  7,
                                     8, 9, 10, 11, 12, 13, 14, 15});
        final MutableSection s1 = new MutableSection();
        s1.setFormatID(formatID);
        s1.setProperty(2, SECTION1);
        ps.addSection(s1);

        final MutableSection s2 = new MutableSection();
        s2.setFormatID(formatID);
        s2.setProperty(2, SECTION2);
        ps.addSection(s2);

        poiFs.createDocument(ps.toInputStream(), STREAM_NAME);
        poiFs.writeFilesystem(out);
        out.close();

        /* Read the POIFS: */
        final PropertySet[] psa = new PropertySet[1];
        final POIFSReader r = new POIFSReader();
        r.registerListener(new POIFSReaderListener()
            {
                public void processPOIFSReaderEvent
                    (final POIFSReaderEvent event)
                {
                    try
                    {
                        psa[0] = PropertySetFactory.create(event.getStream());
                    }
                    catch (Exception ex)
                    {
                        ex.printStackTrace();
                        throw new RuntimeException(ex.toString());
                        /* FIXME (2): Replace the previous line by the following
                         * one once we no longer need JDK 1.3 compatibility. */
                        // throw new RuntimeException(ex);
                    }
                }
            },
            STREAM_NAME);
        r.read(new FileInputStream(filename));
        Assert.assertNotNull(psa[0]);
        Section s = (Section) (psa[0].getSections().get(0));
        assertEquals(s.getFormatID(), formatID);
        Object p = s.getProperty(2);
        Assert.assertEquals(SECTION1, p);
        s = (Section) (psa[0].getSections().get(1));
        p = s.getProperty(2);
        Assert.assertEquals(SECTION2, p);