diff --git a/src/testcases/org/apache/poi/hpsf/basic/POIFile.java b/src/testcases/org/apache/poi/hpsf/basic/POIFile.java index 288242f1c..229dee8fd 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/POIFile.java +++ b/src/testcases/org/apache/poi/hpsf/basic/POIFile.java @@ -72,31 +72,62 @@ public class POIFile private POIFSDocumentPath path; private byte[] bytes; + + /** + *

Sets the POI file's name.

+ * + * @param name The POI file's name. + */ public void setName(final String name) { this.name = name; } + /** + *

Returns the POI file's name.

+ * + * @return The POI file's name. + */ public String getName() { return name; } + /** + *

Sets the POI file's path.

+ * + * @param path The POI file's path. + */ public void setPath(final POIFSDocumentPath path) { this.path = path; } + /** + *

Returns the POI file's path.

+ * + * @return The POI file's path. + */ public POIFSDocumentPath getPath() { return path; } + /** + *

Sets the POI file's content bytes.

+ * + * @param bytes The POI file's content bytes. + */ public void setBytes(final byte[] bytes) { this.bytes = bytes; } + /** + *

Returns the POI file's content bytes.

+ * + * @return The POI file's content bytes. + */ public byte[] getBytes() { return bytes; diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java b/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java index 3e9b147b3..4bf5b98f4 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java +++ b/src/testcases/org/apache/poi/hpsf/basic/TestBasic.java @@ -55,16 +55,11 @@ 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 + /** + *

Test case constructor.

+ * + * @param name The test case's name. + */ public TestBasic(final String name) { super(name); @@ -131,6 +129,9 @@ public class TestBasic extends TestCase /** *

Read a the test file from the "data" directory.

+ * + * @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 /** *

Checks the names of the files in the POI filesystem. They * are expected to be in a certain order.

+ * + * @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}.

+ * + * @exception IOException if an I/O exception occurs */ public void testCreatePropertySets() throws IOException { @@ -206,6 +211,9 @@ public class TestBasic extends TestCase *

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}.

+ * + * @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); } } diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestUnicode.java b/src/testcases/org/apache/poi/hpsf/basic/TestUnicode.java index cf3b351cc..8122bb077 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/TestUnicode.java +++ b/src/testcases/org/apache/poi/hpsf/basic/TestUnicode.java @@ -104,6 +104,9 @@ public class TestUnicode extends TestCase /** *

Read a the test file from the "data" directory.

+ * + * @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 *

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}.

+ * + * @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 /** *

Runs the test cases stand-alone.

+ * + * @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 index 000000000..b74b8f278 --- /dev/null +++ b/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java @@ -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 + * . + */ + +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; + + + +/** + *

Tests HPSF's writing functionality.

+ * + * @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; + + + + /** + *

Constructor

+ * + * @param name the test case's name + */ + public TestWrite(final String name) + { + super(name); + } + + + + /** + * @see TestCase#setUp() + */ + public void setUp() + { + VariantSupport.setLogUnsupportedTypes(false); + } + + + + /** + *

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 + */ + 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); + } + } + } + + + + /** + *

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

+ */ + 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()); + } + } + + + + /** + *

Writes a property and reads it back in.

+ * + * @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); + } + + + + /** + *

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. + */ + 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; + } + + + + /** + *

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:

+ * + * + */ + 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]); + } + + + + /** + *

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

+ * + * @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); + } + } + + + + /** + *

Creates a copy of a {@link PropertySet}.

+ * + * @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; + } + + + + /** + *

Runs the test cases stand-alone.

+ */ + 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); + } + +}