]> source.dussan.org Git - poi.git/commitdiff
Test cases for HPSF writing capability added.
authorRainer Klute <klute@apache.org>
Sat, 30 Aug 2003 09:11:59 +0000 (09:11 +0000)
committerRainer Klute <klute@apache.org>
Sat, 30 Aug 2003 09:11:59 +0000 (09:11 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353320 13f79535-47bb-0310-9956-ffa450edef68

src/testcases/org/apache/poi/hpsf/basic/POIFile.java
src/testcases/org/apache/poi/hpsf/basic/TestBasic.java
src/testcases/org/apache/poi/hpsf/basic/TestUnicode.java
src/testcases/org/apache/poi/hpsf/basic/TestWrite.java [new file with mode: 0644]

index 288242f1c45b9a25c4231af28af8660d08e6fc4f..229dee8fd2fa9f000ebd863a6324e98d7cd10a6e 100644 (file)
@@ -72,31 +72,62 @@ public class POIFile
     private POIFSDocumentPath path;
     private byte[] bytes;
 
+
+    /**
+     * <p>Sets the POI file's name.</p>
+     *
+     * @param name The POI file's name.
+     */
     public void setName(final String name)
     {
         this.name = name;
     }
 
+    /**
+     * <p>Returns the POI file's name.</p>
+     *
+     * @return The POI file's name.
+     */
     public String getName()
     {
         return name;
     }
 
+    /**
+     * <p>Sets the POI file's path.</p>
+     *
+     * @param path The POI file's path.
+     */
     public void setPath(final POIFSDocumentPath path)
     {
         this.path = path;
     }
 
+    /**
+     * <p>Returns the POI file's path.</p>
+     *
+     * @return The POI file's path.
+     */
     public POIFSDocumentPath getPath()
     {
         return path;
     }
 
+    /**
+     * <p>Sets the POI file's content bytes.</p>
+     *
+     * @param bytes The POI file's content bytes.
+     */
     public void setBytes(final byte[] bytes)
     {
         this.bytes = bytes;
     }
 
+    /**
+     * <p>Returns the POI file's content bytes.</p>
+     *
+     * @return The POI file's content bytes.
+     */
     public byte[] getBytes()
     {
         return bytes;
index 3e9b147b332f0ef3233c93535eade62bb0f64968..4bf5b98f421ef23de6637ae87cd8b988411d1fa3 100644 (file)
 package org.apache.poi.hpsf.basic;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileFilter;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
 
 import junit.framework.Assert;
 import junit.framework.TestCase;
@@ -77,8 +72,6 @@ import org.apache.poi.hpsf.PropertySet;
 import org.apache.poi.hpsf.PropertySetFactory;
 import org.apache.poi.hpsf.SummaryInformation;
 import org.apache.poi.hpsf.UnexpectedPropertySetTypeException;
-import org.apache.poi.poifs.filesystem.DocumentEntry;
-import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
 
 
@@ -122,6 +115,11 @@ public class TestBasic extends TestCase
 
 
 
+    /**
+     * <p>Test case constructor.</p>
+     * 
+     * @param name The test case's name.
+     */
     public TestBasic(final String name)
     {
         super(name);
@@ -131,6 +129,9 @@ public class TestBasic extends TestCase
 
     /**
      * <p>Read a the test file from the "data" directory.</p>
+     * 
+     * @exception FileNotFoundException if the file to be read does not exist.
+     * @exception IOException if any other I/O exception occurs.
      */
     public void setUp() throws FileNotFoundException, IOException
     {
@@ -146,6 +147,8 @@ public class TestBasic extends TestCase
     /**
      * <p>Checks the names of the files in the POI filesystem. They
      * are expected to be in a certain order.</p>
+     * 
+     * @exception IOException if an I/O exception occurs
      */
     public void testReadFiles() throws IOException
     {
@@ -164,6 +167,8 @@ public class TestBasic extends TestCase
      * property sets. In the latter cases a {@link
      * NoPropertySetStreamException} will be thrown when trying to
      * create a {@link PropertySet}.</p>
+     * 
+     * @exception IOException if an I/O exception occurs
      */
     public void testCreatePropertySets() throws IOException
     {
@@ -206,6 +211,9 @@ public class TestBasic extends TestCase
      * <p>Tests the {@link PropertySet} methods. The test file has two
      * property sets: the first one is a {@link SummaryInformation},
      * the second one is a {@link DocumentSummaryInformation}.</p>
+     * 
+     * @exception IOException if an I/O exception occurs
+     * @exception HPSFException if any HPSF exception occurs
      */
     public void testPropertySetMethods() throws IOException, HPSFException
     {
@@ -251,7 +259,6 @@ public class TestBasic extends TestCase
             for (int i = 0; i < fileList.length; i++)
             {
                 File f = fileList[i];
-                System.out.println("Reading file " + f);
                 /* Read the POI filesystem's property set streams: */
                 final POIFile[] psf1 = Util.readPropertySets(f);
 
@@ -266,7 +273,7 @@ public class TestBasic extends TestCase
         catch (Throwable t)
         {
             final String s = Util.toString(t);
-            System.err.println(s);
+            fail(s);
         }
     }
 
index cf3b351cc68e086149c4880c0a2523f062ea30ad..8122bb0776331b3197be69cf0c4027253966f69c 100644 (file)
@@ -104,6 +104,9 @@ public class TestUnicode extends TestCase
 
     /**
      * <p>Read a the test file from the "data" directory.</p>
+     * 
+     * @exception FileNotFoundException if the file to be read does not exist.
+     * @exception IOException if any other I/O exception occurs
      */
     protected void setUp() throws FileNotFoundException, IOException
     {
@@ -118,6 +121,9 @@ public class TestUnicode extends TestCase
      * <p>Tests the {@link PropertySet} methods. The test file has two
      * property set: the first one is a {@link SummaryInformation},
      * the second one is a {@link DocumentSummaryInformation}.</p>
+     * 
+     * @exception IOException if an I/O exception occurs
+     * @exception HPSFException if an HPSF exception occurs
      */
     public void testPropertySetMethods() throws IOException, HPSFException
     {
@@ -144,6 +150,8 @@ public class TestUnicode extends TestCase
 
     /**
      * <p>Runs the test cases stand-alone.</p>
+     * 
+     * @param args Command-line arguments.
      */
     public static void main(final String[] args)
     {
diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java b/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java
new file mode 100644 (file)
index 0000000..b74b8f2
--- /dev/null
@@ -0,0 +1,490 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache POI" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache POI", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.poi.hpsf.basic;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Date;
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.hpsf.HPSFRuntimeException;
+import org.apache.poi.hpsf.MutableProperty;
+import org.apache.poi.hpsf.MutablePropertySet;
+import org.apache.poi.hpsf.MutableSection;
+import org.apache.poi.hpsf.Property;
+import org.apache.poi.hpsf.PropertySet;
+import org.apache.poi.hpsf.PropertySetFactory;
+import org.apache.poi.hpsf.Section;
+import org.apache.poi.hpsf.SummaryInformation;
+import org.apache.poi.hpsf.UnsupportedVariantTypeException;
+import org.apache.poi.hpsf.Variant;
+import org.apache.poi.hpsf.VariantSupport;
+import org.apache.poi.hpsf.wellknown.SectionIDMap;
+import org.apache.poi.poifs.eventfilesystem.POIFSReader;
+import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
+import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.LittleEndian;
+
+
+
+/**
+ * <p>Tests HPSF's writing functionality.</p>
+ *
+ * @author Rainer Klute (klute@rainer-klute.de)
+ * @since 2003-02-07
+ * @version $Id$
+ */
+public class TestWrite extends TestCase
+{
+
+    static final String POI_FS = "TestHPSFWritingFunctionality.doc";
+
+    static final int BYTE_ORDER = 0xfffe;
+    static final int FORMAT     = 0x0000;
+    static final int OS_VERSION = 0x00020A04;
+    static final int[] SECTION_COUNT = {1, 2};
+    static final boolean[] IS_SUMMARY_INFORMATION = {true, false};
+    static final boolean[] IS_DOCUMENT_SUMMARY_INFORMATION = {false, true};
+
+    POIFile[] poiFiles;
+
+
+
+    /**
+     * <p>Constructor</p>
+     * 
+     * @param name the test case's name
+     */
+    public TestWrite(final String name)
+    {
+        super(name);
+    }
+
+
+
+    /**
+     * @see TestCase#setUp()
+     */
+    public void setUp()
+    {
+        VariantSupport.setLogUnsupportedTypes(false);
+    }
+
+
+
+    /**
+     * <p>Writes an empty property set to a POIFS and reads it back
+     * in.</p>
+     * 
+     * @exception IOException if an I/O exception occurs
+     * @exception UnsupportedVariantTypeException if HPSF does not yet support
+     * a variant type to be written
+     */
+    public void testWriteEmptyPropertySet()
+        throws IOException, UnsupportedVariantTypeException
+    {
+        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));
+    }
+
+
+
+    static class MyPOIFSReaderListener implements POIFSReaderListener
+    {
+        public void processPOIFSReaderEvent(final POIFSReaderEvent event)
+        {
+            try
+            {
+                PropertySetFactory.create(event.getStream());
+            }
+            catch (Exception ex)
+            {
+                ex.printStackTrace();
+                throw new RuntimeException(ex);
+            }
+        }
+    }
+
+
+
+    /**
+     * <p>Writes and reads back various variant types and checks whether the
+     * stuff that has been read back equals the stuff that was written.</p>
+     */
+    public void testVariantTypes()
+    {
+        Throwable t = null;
+        try
+        {
+            check(Variant.VT_EMPTY, null);
+            check(Variant.VT_BOOL, new Boolean(true));
+            check(Variant.VT_BOOL, new Boolean(false));
+            check(Variant.VT_CF, new byte[]{0});
+            check(Variant.VT_CF, new byte[]{0, 1});
+            check(Variant.VT_CF, new byte[]{0, 1, 2});
+            check(Variant.VT_CF, new byte[]{0, 1, 2, 3});
+            check(Variant.VT_CF, new byte[]{0, 1, 2, 3, 4});
+            check(Variant.VT_CF, new byte[]{0, 1, 2, 3, 4, 5});
+            check(Variant.VT_CF, new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
+            check(Variant.VT_I2, new Integer(27));
+            check(Variant.VT_I4, new Long(28));
+            check(Variant.VT_FILETIME, new Date());
+            check(Variant.VT_LPSTR, "");
+            check(Variant.VT_LPSTR, "ä");
+            check(Variant.VT_LPSTR, "äö");
+            check(Variant.VT_LPSTR, "äöü");
+            check(Variant.VT_LPSTR, "äöüÄ");
+            check(Variant.VT_LPSTR, "äöüÄÖ");
+            check(Variant.VT_LPSTR, "äöüÄÖÜ");
+            check(Variant.VT_LPSTR, "äöüÄÖÜß");
+            check(Variant.VT_LPWSTR, "");
+            check(Variant.VT_LPWSTR, "ä");
+            check(Variant.VT_LPWSTR, "äö");
+            check(Variant.VT_LPWSTR, "äöü");
+            check(Variant.VT_LPWSTR, "äöüÄ");
+            check(Variant.VT_LPWSTR, "äöüÄÖ");
+            check(Variant.VT_LPWSTR, "äöüÄÖÜ");
+            check(Variant.VT_LPWSTR, "äöüÄÖÜß");
+        }
+        catch (Exception ex)
+        {
+            t = ex;
+        }
+        catch (Error ex)
+        {
+            t = ex;
+        }
+        if (t != null)
+        {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            t.printStackTrace(pw);
+            pw.close();
+            try
+            {
+                sw.close();
+            }
+            catch (IOException ex2)
+            {
+                t.printStackTrace();
+            }
+            fail(sw.toString());
+        }
+    }
+
+
+
+    /**
+     * <p>Writes a property and reads it back in.</p>
+     *
+     * @param variantType The property's variant type.
+     * @param value The property's value.
+     * @throws UnsupportedVariantTypeException if the variant is not supported.
+     * @throws IOException if an I/O exception occurs.
+     */
+    private void check(final long variantType, final Object value)
+        throws UnsupportedVariantTypeException, IOException
+    {
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        VariantSupport.write(out, variantType, value);
+        out.close();
+        final byte[] b = out.toByteArray();
+        final Object objRead =
+            VariantSupport.read(b, 0, b.length + LittleEndian.INT_SIZE,
+                                variantType);
+        if (objRead instanceof byte[])
+        {
+            final int diff = diff(org.apache.poi.hpsf.Util.pad4
+                ((byte[]) value), (byte[]) objRead);
+            if (diff >= 0)
+                fail("Byte arrays are different. First different byte is at " +
+                     "index " + diff + ".");
+        }
+        else
+            assertEquals(value, objRead);
+    }
+
+
+
+    /**
+     * <p>Compares two byte arrays.</p>
+     *
+     * @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.
+     */
+    private int diff(final byte[] a, final byte[] b)
+    {
+        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;
+    }
+
+
+
+    /**
+     * <p>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:</p>
+     * 
+     * <ul>
+     * 
+     * <li><p>Read its property set streams.</p></li>
+     * 
+     * <li><p>Create a new POI filesystem containing the origin file's
+     * property set streams.</p></li>
+     * 
+     * <li><p>Read the property set streams from the POI filesystem just
+     * created.</p></li>
+     * 
+     * <li><p>Compare each property set stream with the corresponding one from
+     * the origin file and check whether they are equal.</p></li>
+     *
+     * </ul>
+     */
+    public void testRecreate()
+    {
+        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.isFile();
+                }
+            });
+        for (int i = 0; i < fileList.length; i++)
+            testRecreate(fileList[i]);
+    }
+
+
+
+    /**
+     * <p>Performs the check described in {@link #testRecreate()} for a single
+     * POI filesystem.</p>
+     *
+     * @param f the POI filesystem to check
+     */
+    private void testRecreate(final 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 = File.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 = copy(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(ps1, ps2);
+            }
+        }
+        catch (Exception ex)
+        {
+            StringWriter sw = new StringWriter();
+            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();
+            }
+            String msg = sw.toString();
+            fail(msg);
+        }
+    }
+
+
+
+    /**
+     * <p>Creates a copy of a {@link PropertySet}.</p>
+     *
+     * @param ps the property set to copy
+     * @return the copy
+     */
+    private MutablePropertySet copy(final PropertySet ps)
+    {
+        MutablePropertySet copy = new MutablePropertySet();
+        copy.setByteOrder(ps.getByteOrder());
+        copy.setClassID(ps.getClassID());
+        copy.setFormat(ps.getFormat());
+        copy.setOSVersion(ps.getOSVersion());
+        copy.clearSections();
+
+        /* Copy the sections. */
+        for (final Iterator i1 = ps.getSections().iterator(); i1.hasNext();)
+        {
+            final Section s1 = (Section) i1.next();
+            final MutableSection s2 = new MutableSection();
+            s2.setFormatID(s1.getFormatID());
+
+            /* Copy the properties. */
+            final Property[] pa = s1.getProperties();
+            for (int i2 = 0; i2 < pa.length; i2++)
+            {
+                final Property p1 = pa[i2];
+                final MutableProperty p2 = new MutableProperty();
+                p2.setID(p1.getID());
+                p2.setType(p1.getType());
+                p2.setValue(p1.getValue());
+                s2.setProperty(p2);
+            }
+            copy.addSection(s2);
+        }
+        return copy;
+    }
+
+
+
+    /**
+     * <p>Runs the test cases stand-alone.</p>
+     */
+    public static void main(final String[] args) throws Throwable
+    {
+        System.setProperty("HPSF.testdata.path",
+                           "./src/testcases/org/apache/poi/hpsf/data");
+        junit.textui.TestRunner.run(TestWrite.class);
+    }
+
+}