diff --git a/src/documentation/xdocs/hpsf/how-to.xml b/src/documentation/xdocs/hpsf/how-to.xml
index 826e60cb8..ec88ddcfe 100644
--- a/src/documentation/xdocs/hpsf/how-to.xml
+++ b/src/documentation/xdocs/hpsf/how-to.xml
@@ -95,9 +95,6 @@
examples section of the POI source tree as
ReadTitle.java .
-
import java.io.*;
import org.apache.poi.hpsf.*;
@@ -317,18 +314,139 @@ else
value .
Okay, that was still rather easy. However, to make things more
- complicated Microsoft in its infinite wisdom decided that a property set
+ complicated, Microsoft in its infinite wisdom decided that a property set
shalt be broken into sections . Each section holds a bunch
- of properties. But since that's still not complicated enough: a section
+ of properties. But since that's still not complicated enough: A section
can optionally have a dictionary that maps property IDs to property
names - we'll explain later what that means.
- [To be continued.]
+ So the procedure to get to the properties is as follows:
- Let's consider a Java application that wants to read a stream
- containing a general property set. It is modelled by the class
- PropertySet
in the org.apache.poi.hpsf
- package.
+
+ Use the PropertySetFactory
to create a
+ PropertySet
from an input stream. You can try this with any
+ input stream: You'll either PropertySet
instance or an
+ exception is thrown.
+
+ Call the PropertySet
's method getSections()
+ to get a list of sections contained in the property set. Each section is
+ an instance of the Section
class.
+
+ Each section has a format ID. The format ID of the first section in a
+ property set determines the property set's type. For example, the first
+ (and only) section of the SummaryInformation property set has a format ID
+ of F29F85E0-4FF9-1068-AB-91-08-00-2B-27-B3-D9
. You can
+ get the format ID with Section.getFormatID()
.
+
+ The properties contained in a Section
can be retrieved
+ with Section.getProperties()
. The result is an array of
+ Property
instances.
+
+ A property has a name, a type, and a value. The Property
+ class has methods to retrieve them.
+
+
+ Let's have a look at a sample Java application that dumps all property
+ set streams contained in a POI file system. The full source code of this
+ program can be found as ReadCustomPropertySets.java in the
+ examples area of the POI source code tree. Here are the key
+ sections:
+
+ import java.io.*;
+import java.util.*;
+import org.apache.poi.hpsf.*;
+import org.apache.poi.poifs.eventfilesystem.*;
+import org.apache.poi.util.HexDump;
+
+ The most important package the application needs is
+ org.apache.poi.hpsf.*
. This package contains the HPSF
+ classes. Most classes named below are from the HPSF package. Of course we
+ also need the POIFS event file system's classes and java.io.*
+ since we are dealing with POI I/O. From the java.util
package
+ we use the List
and Iterator
class. The class
+ org.apache.poi.util.HexDump
provides a methods to dump byte
+ arrays as nicely formatted strings.
+
+ public static void main(String[] args)
+ throws IOException
+{
+ final String filename = args[0];
+ POIFSReader r = new POIFSReader();
+
+ /* Register a listener for *all* documents. */
+ r.registerListener(new MyPOIFSReaderListener());
+ r.read(new FileInputStream(filename));
+}
+
+ The POIFSReader
is set up in a way that the listener
+ MyPOIFSReaderListener
is called on every file in the POI file
+ system.
+
+ The listener class tries to create a PropertySet
from each
+ stream using the PropertySetFactory.create()
method:
+
+ static class MyPOIFSReaderListener implements POIFSReaderListener
+{
+ public void processPOIFSReaderEvent(POIFSReaderEvent event)
+ {
+ PropertySet ps = null;
+ try
+ {
+ ps = PropertySetFactory.create(event.getStream());
+ }
+ catch (NoPropertySetStreamException ex)
+ {
+ out("No property set stream: \"" + event.getPath() +
+ event.getName() + "\"");
+ return;
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException
+ ("Property set stream \"" +
+ event.getPath() + event.getName() + "\": " + ex);
+ }
+
+ /* Print the name of the property set stream: */
+ out("Property set stream \"" + event.getPath() +
+ event.getName() + "\":");
+
+ Creating the PropertySet
is done in a try
+ block, because not each stream in the POI file system contains a property
+ set. If it is some other file, the
+ PropertySetFactory.create()
throws a
+ NoPropertySetStreamException
, which is caught and
+ logged. Then the program continues with the next stream. However, all
+ other types of exceptions cause the program to terminate by throwing a
+ runtime exception. If all went well, we can print the name of the property
+ set stream.
+
+ The next step is to print the number of sections followed by the
+ sections themselves:
+
+ /* Print the number of sections: */
+final long sectionCount = ps.getSectionCount();
+out(" No. of sections: " + sectionCount);
+
+/* Print the list of sections: */
+List sections = ps.getSections();
+int nr = 0;
+for (Iterator i = sections.iterator(); i.hasNext();)
+{
+ /* Print a single section: */
+ Section sec = (Section) i.next();
+
+ // ...
+}
+
+ The PropertySet
's method getSectionCount()
+ returns the number of sections.
+
+ To retrieve the sections, use the getSections()
+ method. This method returns a java.util.List
containing
+ instances of the Section
class in their proper order.
+
+ [To be continued.]