Writing: API enhanced, bugs fixed, performance improvements, code simplifications, two new testcases, more int to long promotions.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353341 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
495dfa3eb7
commit
69581f5f0d
@ -26,6 +26,20 @@ public class MutableProperty extends Property
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Creates a <code>MutableProperty</code> as a copy of an existing
|
||||
* <code>Property</code>.</p>
|
||||
*
|
||||
* @param p The property to copy.
|
||||
*/
|
||||
public MutableProperty(final Property p)
|
||||
{
|
||||
setID(p.getID());
|
||||
setType(p.getType());
|
||||
setValue(p.getValue());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Sets the property's ID.</p>
|
||||
*
|
||||
|
@ -59,6 +59,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ListIterator;
|
||||
|
||||
@ -109,6 +110,30 @@ public class MutablePropertySet extends PropertySet
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>MutablePropertySet</code> by doing a deep copy of
|
||||
* an existing <code>PropertySet</code>. All nested elements, i.e.
|
||||
* <code>Section</code>s and <code>Property</code> instances, will be their
|
||||
* mutable counterparts in the new <code>MutablePropertySet</code>.</p>
|
||||
*
|
||||
* @param ps The property set to copy
|
||||
*/
|
||||
public MutablePropertySet(final PropertySet ps)
|
||||
{
|
||||
byteOrder = ps.getByteOrder();
|
||||
format = ps.getFormat();
|
||||
osVersion = ps.getOSVersion();
|
||||
classID = new ClassID(ps.getClassID().getBytes(), 0);
|
||||
clearSections();
|
||||
for (final Iterator i = ps.getSections().iterator(); i.hasNext();)
|
||||
{
|
||||
final MutableSection s = new MutableSection((Section) (i.next()));
|
||||
addSection(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>The length of the property set stream header.</p>
|
||||
*/
|
||||
@ -178,6 +203,7 @@ public class MutablePropertySet extends PropertySet
|
||||
public void clearSections()
|
||||
{
|
||||
sections = null;
|
||||
sectionCount = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -194,6 +220,7 @@ public class MutablePropertySet extends PropertySet
|
||||
if (sections == null)
|
||||
sections = new LinkedList();
|
||||
sections.add(section);
|
||||
sectionCount = sections.size();
|
||||
}
|
||||
|
||||
|
||||
@ -223,13 +250,16 @@ public class MutablePropertySet extends PropertySet
|
||||
int offset = OFFSET_HEADER;
|
||||
|
||||
/* Write the section list, i.e. the references to the sections. Each
|
||||
* entry in the section list consist of a class ID and the offset to the
|
||||
* section's begin. */
|
||||
* entry in the section list consist of the section's class ID and the
|
||||
* section's offset relative to the beginning of the stream. */
|
||||
offset += nrSections * (ClassID.LENGTH + LittleEndian.INT_SIZE);
|
||||
final int sectionsBegin = offset;
|
||||
for (final ListIterator i = sections.listIterator(); i.hasNext();)
|
||||
{
|
||||
final MutableSection s = (MutableSection) i.next();
|
||||
final ClassID formatID = s.getFormatID();
|
||||
if (formatID == null)
|
||||
throw new NoFormatIDException();
|
||||
length += TypeWriter.writeToStream(out, s.getFormatID());
|
||||
length += TypeWriter.writeUIntToStream(out, offset);
|
||||
offset += s.getSize();
|
||||
@ -240,7 +270,7 @@ public class MutablePropertySet extends PropertySet
|
||||
for (final ListIterator i = sections.listIterator(); i.hasNext();)
|
||||
{
|
||||
final MutableSection s = (MutableSection) i.next();
|
||||
offset = s.write(out, offset);
|
||||
offset += s.write(out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,14 +70,11 @@ import org.apache.poi.util.LittleEndianConsts;
|
||||
* <p>Please be aware that this class' functionality will be merged into the
|
||||
* {@link Section} class at a later time, so the API will change.</p>
|
||||
*
|
||||
* @author Rainer Klute <a
|
||||
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
|
||||
* @version $Id$
|
||||
* @since 2002-02-20
|
||||
*/
|
||||
public class MutableSection extends Section
|
||||
{
|
||||
|
||||
/**
|
||||
* <p>If the "dirty" flag is true, the section's size must be
|
||||
* (re-)calculated before the section is written.</p>
|
||||
@ -95,6 +92,15 @@ public class MutableSection extends Section
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Contains the bytes making out the section. This byte array is
|
||||
* established when the section's size is calculated and can be reused
|
||||
* later. It is valid only if the "dirty" flag is false.</p>
|
||||
*/
|
||||
private byte[] sectionBytes;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Creates an empty mutable section.</p>
|
||||
*/
|
||||
@ -108,6 +114,26 @@ public class MutableSection extends Section
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>MutableSection</code> by doing a deep copy of an
|
||||
* existing <code>Section</code>. All nested <code>Property</code>
|
||||
* instances, will be their mutable counterparts in the new
|
||||
* <code>MutableSection</code>.</p>
|
||||
*
|
||||
* @param s The section set to copy
|
||||
*/
|
||||
public MutableSection(final Section s)
|
||||
{
|
||||
setFormatID(s.getFormatID());
|
||||
final Property[] pa = s.getProperties();
|
||||
final MutableProperty[] mpa = new MutableProperty[pa.length];
|
||||
for (int i = 0; i < pa.length; i++)
|
||||
mpa[i] = new MutableProperty(pa[i]);
|
||||
setProperties(mpa);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Sets the section's format ID.</p>
|
||||
*
|
||||
@ -146,10 +172,12 @@ public class MutableSection extends Section
|
||||
*/
|
||||
public void setProperties(final Property[] properties)
|
||||
{
|
||||
this.properties = properties;
|
||||
preprops = new LinkedList();
|
||||
for (int i = 0; i < properties.length; i++)
|
||||
preprops.add(properties[i]);
|
||||
dirty = true;
|
||||
propertyCount = properties.length;
|
||||
}
|
||||
|
||||
|
||||
@ -164,7 +192,7 @@ public class MutableSection extends Section
|
||||
* @param value The property's value. It will be written as a Unicode
|
||||
* string.
|
||||
*
|
||||
* @see #setProperty(int, int, Object)
|
||||
* @see #setProperty(int, long, Object)
|
||||
* @see #getProperty
|
||||
*/
|
||||
public void setProperty(final int id, final String value)
|
||||
@ -186,7 +214,7 @@ public class MutableSection extends Section
|
||||
* @param variantType The property's variant type.
|
||||
* @param value The property's value.
|
||||
*
|
||||
* @see #setProperty(int, Object)
|
||||
* @see #setProperty(int, String)
|
||||
* @see #getProperty
|
||||
* @see Variant
|
||||
*/
|
||||
@ -211,7 +239,7 @@ public class MutableSection extends Section
|
||||
*
|
||||
* @param p The property to be added to the section
|
||||
*
|
||||
* @see #setProperty(int, int, Object)
|
||||
* @see #setProperty(int, long, Object)
|
||||
* @see #setProperty(int, String)
|
||||
* @see #getProperty
|
||||
* @see Variant
|
||||
@ -227,6 +255,7 @@ public class MutableSection extends Section
|
||||
}
|
||||
preprops.add(p);
|
||||
dirty = true;
|
||||
propertyCount = preprops.size();
|
||||
}
|
||||
|
||||
|
||||
@ -238,7 +267,7 @@ public class MutableSection extends Section
|
||||
* @param id The property's ID
|
||||
* @param value The property's value
|
||||
*
|
||||
* @see #setProperty(int, int, Object)
|
||||
* @see #setProperty(int, long, Object)
|
||||
* @see #getProperty
|
||||
* @see Variant
|
||||
*/
|
||||
@ -258,8 +287,15 @@ public class MutableSection extends Section
|
||||
{
|
||||
if (dirty)
|
||||
{
|
||||
size = calcSize();
|
||||
dirty = false;
|
||||
try
|
||||
{
|
||||
size = calcSize();
|
||||
dirty = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new HPSFRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@ -273,58 +309,13 @@ public class MutableSection extends Section
|
||||
*
|
||||
* @return the section's length in bytes.
|
||||
*/
|
||||
private int calcSize()
|
||||
private int calcSize() throws WritingNotSupportedException, IOException
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
/* The section header. */
|
||||
length += LittleEndianConsts.INT_SIZE * 2;
|
||||
|
||||
/* The length of the property list. */
|
||||
Property[] psa = getProperties();
|
||||
if (psa == null)
|
||||
psa = new MutableProperty[0];
|
||||
length += psa.length * LittleEndianConsts.INT_SIZE * 3;
|
||||
|
||||
/* The sum of the lengths of the properties - it is calculated by simply
|
||||
* writing the properties to a temporary byte array output stream: */
|
||||
final ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
for (int i = 0; i < psa.length; i++)
|
||||
{
|
||||
final MutableProperty mp = new MutableProperty();
|
||||
mp.setID(psa[i].getID());
|
||||
mp.setType(psa[i].getType());
|
||||
mp.setValue(psa[i].getValue());
|
||||
try
|
||||
{
|
||||
length += mp.write(b);
|
||||
}
|
||||
catch (WritingNotSupportedException ex)
|
||||
{
|
||||
/* It was not possible to write the property, not even as a
|
||||
* byte array. We cannot do anything about that. Instead of the
|
||||
* property we insert an empty one into the stream. */
|
||||
mp.setType(Variant.VT_EMPTY);
|
||||
mp.setValue(null);
|
||||
try
|
||||
{
|
||||
length += mp.write(b);
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
/* Even writing an empty property went awfully wrong.
|
||||
* Let's give up. */
|
||||
throw new HPSFRuntimeException(ex2);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
/* Should never occur. */
|
||||
throw new HPSFRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
write(out);
|
||||
out.close();
|
||||
sectionBytes = out.toByteArray();
|
||||
return sectionBytes.length;
|
||||
}
|
||||
|
||||
|
||||
@ -337,19 +328,24 @@ public class MutableSection extends Section
|
||||
* the section as such. The two former are appended to the latter when they
|
||||
* have received all their data.</p>
|
||||
*
|
||||
* @param out The stream to write into
|
||||
* @param offset The offset from the beginning of the property set
|
||||
* stream this section begins at
|
||||
* @param out The stream to write into.
|
||||
*
|
||||
* @return The offset of the first byte following this section in
|
||||
* the property set stream.
|
||||
* @return The number of bytes written, i.e. the section's size.
|
||||
* @exception IOException if an I/O error occurs
|
||||
* @exception WritingNotSupportedException if HPSF does not yet support
|
||||
* writing a property's variant type.
|
||||
*/
|
||||
public int write(final OutputStream out, final int offset)
|
||||
public int write(final OutputStream out)
|
||||
throws WritingNotSupportedException, IOException
|
||||
{
|
||||
/* Check whether we have already generated the bytes making out the
|
||||
* section. */
|
||||
if (!dirty && sectionBytes != null)
|
||||
{
|
||||
out.write(sectionBytes);
|
||||
return sectionBytes.length;
|
||||
}
|
||||
|
||||
/* The properties are written to this stream. */
|
||||
final ByteArrayOutputStream propertyStream =
|
||||
new ByteArrayOutputStream();
|
||||
@ -364,7 +360,8 @@ public class MutableSection extends Section
|
||||
int position = 0;
|
||||
|
||||
/* Increase the position variable by the size of the property list so
|
||||
* that it points to the beginning of the properties themselves. */
|
||||
* that it points behind the property list and to the beginning of the
|
||||
* properties themselves. */
|
||||
position += 2 * LittleEndian.INT_SIZE +
|
||||
getPropertyCount() * 2 * LittleEndian.INT_SIZE;
|
||||
|
||||
@ -388,13 +385,22 @@ public class MutableSection extends Section
|
||||
/* Write the section: */
|
||||
byte[] pb1 = propertyListStream.toByteArray();
|
||||
byte[] pb2 = propertyStream.toByteArray();
|
||||
TypeWriter.writeToStream(out, LittleEndian.INT_SIZE * 2 + pb1.length +
|
||||
pb2.length);
|
||||
|
||||
/* Write the section's length: */
|
||||
TypeWriter.writeToStream(out, LittleEndian.INT_SIZE * 2 +
|
||||
pb1.length + pb2.length);
|
||||
|
||||
/* Write the section's number of properties: */
|
||||
TypeWriter.writeToStream(out, getPropertyCount());
|
||||
|
||||
/* Write the property list: */
|
||||
out.write(pb1);
|
||||
|
||||
/* Write the properties: */
|
||||
out.write(pb2);
|
||||
|
||||
return offset + position;
|
||||
int streamLength = LittleEndian.INT_SIZE * 2 + pb1.length + pb2.length;
|
||||
return streamLength;
|
||||
}
|
||||
|
||||
|
||||
|
@ -209,6 +209,9 @@ public class PropertySet
|
||||
|
||||
/**
|
||||
* <p>The number of sections in this {@link PropertySet}.</p>
|
||||
*
|
||||
* <p>FIXME (2): Get rid of this! The number of sections is implicitly
|
||||
* available.</p>
|
||||
*/
|
||||
protected int sectionCount;
|
||||
|
||||
@ -474,7 +477,7 @@ public class PropertySet
|
||||
* Summary Information stream has 2. Everything else is a rare
|
||||
* exception and is no longer fostered by Microsoft.
|
||||
*/
|
||||
sections = new ArrayList(2);
|
||||
sections = new ArrayList(sectionCount);
|
||||
|
||||
/*
|
||||
* Loop over the section descriptor array. Each descriptor
|
||||
|
@ -142,9 +142,12 @@ public class Section
|
||||
|
||||
|
||||
/**
|
||||
* FIXME (2): Get rid of this! The property count is implicitly available as
|
||||
* the length of the "properties" array.
|
||||
*
|
||||
* @see #getPropertyCount
|
||||
*/
|
||||
private int propertyCount;
|
||||
protected int propertyCount;
|
||||
|
||||
|
||||
/**
|
||||
@ -162,7 +165,7 @@ public class Section
|
||||
/**
|
||||
* @see #getProperties
|
||||
*/
|
||||
private Property[] properties;
|
||||
protected Property[] properties;
|
||||
|
||||
|
||||
/**
|
||||
@ -175,16 +178,6 @@ public class Section
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets this section's properties.</p>
|
||||
*
|
||||
* @param properties This section's new properties.
|
||||
*/
|
||||
protected void setProperties(final Property[] properties)
|
||||
{
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -383,7 +376,7 @@ public class Section
|
||||
*
|
||||
* @return The property's value
|
||||
*/
|
||||
public Object getProperty(final int id)
|
||||
public Object getProperty(final long id)
|
||||
{
|
||||
wasNull = false;
|
||||
for (int i = 0; i < properties.length; i++)
|
||||
@ -406,9 +399,9 @@ public class Section
|
||||
*
|
||||
* @return The property's value
|
||||
*/
|
||||
protected int getPropertyIntValue(final int id)
|
||||
protected int getPropertyIntValue(final long id)
|
||||
{
|
||||
final Integer i = (Integer) getProperty(id);
|
||||
final Long i = (Long) getProperty(id);
|
||||
if (i != null)
|
||||
return i.intValue();
|
||||
else
|
||||
|
@ -54,6 +54,9 @@
|
||||
*/
|
||||
package org.apache.poi.hpsf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
@ -337,4 +340,36 @@ public class Util
|
||||
return pad4(s.toCharArray());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Returns a textual representation of a {@link Throwable}, including a
|
||||
* stacktrace.</p>
|
||||
*
|
||||
* @param t The {@link Throwable}
|
||||
*
|
||||
* @return a string containing the output of a call to
|
||||
* <code>t.printStacktrace()</code>.
|
||||
*/
|
||||
public static String toString(final Throwable t)
|
||||
{
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
t.printStackTrace(pw);
|
||||
pw.close();
|
||||
try
|
||||
{
|
||||
sw.close();
|
||||
return sw.toString();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
final StringBuffer b = new StringBuffer(t.getMessage());
|
||||
b.append("\n");
|
||||
b.append("Could not create a stacktrace. Reason: ");
|
||||
b.append(e.getMessage());
|
||||
return b.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -290,9 +290,9 @@ public class PropertyIDMap extends HashMap
|
||||
* <var>id</var>, or <code>null</code> if there was no mapping for
|
||||
* key.
|
||||
*/
|
||||
public Object put(final int id, final String idString)
|
||||
public Object put(final long id, final String idString)
|
||||
{
|
||||
return put(new Integer(id), idString);
|
||||
return put(new Long(id), idString);
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,7 +272,7 @@ public class TestBasic extends TestCase
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
final String s = Util.toString(t);
|
||||
final String s = org.apache.poi.hpsf.Util.toString(t);
|
||||
fail(s);
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ 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.NoFormatIDException;
|
||||
import org.apache.poi.hpsf.Property;
|
||||
import org.apache.poi.hpsf.PropertySet;
|
||||
import org.apache.poi.hpsf.PropertySetFactory;
|
||||
@ -83,6 +84,7 @@ 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.WritingNotSupportedException;
|
||||
import org.apache.poi.hpsf.wellknown.PropertyIDMap;
|
||||
import org.apache.poi.hpsf.wellknown.SectionIDMap;
|
||||
import org.apache.poi.poifs.eventfilesystem.POIFSReader;
|
||||
@ -138,6 +140,55 @@ public class TestWrite extends TestCase
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <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 testNoFormatID()
|
||||
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 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Writes an empty property set to a POIFS and reads it back
|
||||
* in.</p>
|
||||
@ -180,8 +231,8 @@ public class TestWrite extends TestCase
|
||||
|
||||
|
||||
/**
|
||||
* <p>Writes a simple property set with a SummaryInformation and a
|
||||
* DocumentSummaryInformation stream to a POIFS and reads it back in.</p>
|
||||
* <p>Writes a simple property set with a SummaryInformation section 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
|
||||
@ -198,24 +249,24 @@ public class TestWrite extends TestCase
|
||||
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();
|
||||
@ -234,7 +285,7 @@ public class TestWrite extends TestCase
|
||||
throw new RuntimeException(ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
SummaryInformation.DEFAULT_STREAM_NAME);
|
||||
r.read(new FileInputStream(filename));
|
||||
@ -248,6 +299,80 @@ public class TestWrite extends TestCase
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Writes a simple property set with two sections to a POIFS and reads it
|
||||
* back in.</p>
|
||||
*
|
||||
* @exception IOException if an I/O exception occurs
|
||||
* @exception WritingNotSupportedException if HPSF does not yet support
|
||||
* a variant type to be written
|
||||
*/
|
||||
public void testWriteTwoSections()
|
||||
throws WritingNotSupportedException, IOException
|
||||
{
|
||||
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 byte[] formatID =
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
STREAM_NAME);
|
||||
r.read(new FileInputStream(filename));
|
||||
Assert.assertNotNull(psa[0]);
|
||||
Section s = (Section) (psa[0].getSections().get(0));
|
||||
Object p = s.getProperty(2);
|
||||
Assert.assertEquals(SECTION1, p);
|
||||
s = (Section) (psa[0].getSections().get(1));
|
||||
p = s.getProperty(2);
|
||||
Assert.assertEquals(SECTION2, p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static class MyPOIFSReaderListener implements POIFSReaderListener
|
||||
{
|
||||
public void processPOIFSReaderEvent(final POIFSReaderEvent event)
|
||||
|
@ -62,8 +62,6 @@ import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@ -301,34 +299,4 @@ public class Util
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>Returns a textual representation of a {@link Throwable}, including a
|
||||
* stacktrace.</p>
|
||||
*
|
||||
* @param t The {@link Throwable}
|
||||
*
|
||||
* @return a string containing the output of a call to
|
||||
* <code>t.printStacktrace()</code>.
|
||||
*/
|
||||
public static String toString(final Throwable t)
|
||||
{
|
||||
final StringWriter sw = new StringWriter();
|
||||
final PrintWriter pw = new PrintWriter(sw);
|
||||
t.printStackTrace(pw);
|
||||
pw.close();
|
||||
try
|
||||
{
|
||||
sw.close();
|
||||
return sw.toString();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
final StringBuffer b = new StringBuffer(t.getMessage());
|
||||
b.append("\n");
|
||||
b.append("Could not create a stacktrace. Reason: ");
|
||||
b.append(e.getMessage());
|
||||
return b.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user