195 lines
6.9 KiB
XML
195 lines
6.9 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd">
|
|
|
|
<document>
|
|
<header>
|
|
<title>Record Generator HOWTO</title>
|
|
<authors>
|
|
<person email="glens@apache.org" name="Glen Stampoultzis" id="glens"/>
|
|
<person email="acoliver@apache.org" name="Andrew C. Oliver" id="acoliver"/>
|
|
</authors>
|
|
</header>
|
|
<body>
|
|
<section><title>How to Use the Record Generator</title>
|
|
|
|
<section><title>History</title>
|
|
<p>
|
|
The record generator was born from frustration with translating
|
|
the Excel records to Java classes. Doing this manually is a time
|
|
consuming process. It's also very easy to make mistakes.
|
|
</p>
|
|
<p>
|
|
A utility was needed to take the defintition of what a
|
|
record looked like and do all the boring and repetitive work.
|
|
</p>
|
|
</section>
|
|
|
|
<section><title>Capabilities</title>
|
|
<p>
|
|
The record generator takes XML as input and produces the following
|
|
output:
|
|
</p>
|
|
<ul>
|
|
<li>A Java file capabile of decoding and encoding the record.</li>
|
|
<li>A test class that provides a fill-in-the-blanks implementation
|
|
of a test case for ensuring the record operates as
|
|
designed.</li>
|
|
</ul>
|
|
</section>
|
|
<section><title>Usage</title>
|
|
<p>
|
|
The record generator is invoked as an Ant target
|
|
(generate-records). It goes through looking for all files in
|
|
<code>src/records/defintitions</code> ending with _record.xml.
|
|
It then creates two files; the Java record definition and the
|
|
Java test case template.
|
|
</p>
|
|
<p>
|
|
The records themselves have the following general layout:
|
|
</p>
|
|
<source><![CDATA[
|
|
<record id="0x1032" name="Frame" package="org.apache.poi.hssf.record"
|
|
excel-record-id="FRAME">
|
|
<description>The frame record indicates whether there is a border
|
|
around the displayed text of a chart.</description>
|
|
<author>Glen Stampoultzis (glens at apache.org)</author>
|
|
<fields>
|
|
<field type="int" size="2" name="border type">
|
|
<const name="regular" value="0" description="regular rectangle or no border"/>
|
|
<const name="shadow" value="1" description="rectangle with shadow"/>
|
|
</field>
|
|
<field type="int" size="2" name="options">
|
|
<bit number="0" name="auto size"
|
|
description="excel calculates the size automatically if true"/>
|
|
<bit number="1" name="auto position"
|
|
description="excel calculates the position automatically"/>
|
|
</field>
|
|
</fields>
|
|
</record>
|
|
]]></source>
|
|
<p>
|
|
The following table details the allowable types and sizes for
|
|
the fields.
|
|
</p>
|
|
<table>
|
|
<tr>
|
|
<th>Type</th>
|
|
<th>Size</th>
|
|
<th>Java Type</th>
|
|
</tr>
|
|
<tr>
|
|
<td>int</td>
|
|
<td>1</td>
|
|
<td>byte</td>
|
|
</tr>
|
|
<tr>
|
|
<td>int</td>
|
|
<td>2</td>
|
|
<td>short</td>
|
|
</tr>
|
|
<tr>
|
|
<td>int</td>
|
|
<td>4</td>
|
|
<td>int</td>
|
|
</tr>
|
|
<tr>
|
|
<td>int</td>
|
|
<td>8</td>
|
|
<td>long</td>
|
|
</tr>
|
|
<tr>
|
|
<td>int</td>
|
|
<td>varword</td>
|
|
<td>array of shorts</td>
|
|
</tr>
|
|
<tr>
|
|
<td>bits</td>
|
|
<td>1</td>
|
|
<td>A byte comprising of a bits (defined by the bit element)
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>bits</td>
|
|
<td>2</td>
|
|
<td>An short comprising of a bits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>bits</td>
|
|
<td>4</td>
|
|
<td>A int comprising of a bits</td>
|
|
</tr>
|
|
<tr>
|
|
<td>float</td>
|
|
<td>8</td>
|
|
<td>double</td>
|
|
</tr>
|
|
<tr>
|
|
<td>hbstring</td>
|
|
<td>java expression</td>
|
|
<td>String</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
The Java records are regenerated each time the record generator is
|
|
run, however the test stubs are only created if the test stub does
|
|
not already exist. What this means is that you may change test
|
|
stubs but not the generated records.
|
|
</p>
|
|
</section>
|
|
<section><title>Custom Field Types</title>
|
|
<p>
|
|
Occationally the builtin types are not enough. More control
|
|
over the encoding and decoding of the streams is required. This
|
|
can be achieved using a custom type.
|
|
</p>
|
|
<p>
|
|
A custom type lets you escape to java to define the way in which
|
|
the field encodes and decodes. To code a custom type you
|
|
declare your field like this:
|
|
</p>
|
|
<source><![CDATA[
|
|
<field type="custom:org.apache.poi.hssf.record.LinkedDataFormulaField"
|
|
size="var" name="formula of link" description="formula"/>
|
|
]]></source>
|
|
<p>
|
|
Where the class name specified after <code>custom:</code> is a
|
|
class implementing the interface <code>CustomField</code>.
|
|
</p>
|
|
<p>
|
|
You can then implement the encoding yourself.
|
|
</p>
|
|
</section>
|
|
<section><title>How it Works</title>
|
|
<p>
|
|
The record generation works by taking an XML file and styling it
|
|
using XLST. Given that XSLT is a little limited in some ways it was
|
|
necessary to add a little Java code to the mix.
|
|
</p>
|
|
<p>
|
|
See record.xsl, record_test.xsl, FieldIterator.java,
|
|
RecordUtil.java, RecordGenerator.java
|
|
</p>
|
|
<p>
|
|
There is a corresponding "type" generator for HDF.
|
|
See the HDF documentation for details.
|
|
</p>
|
|
</section>
|
|
<section><title>Limitations</title>
|
|
<p>
|
|
The record generator does not handle all possible record types and
|
|
goes not intend to perform this function. When dealing with a
|
|
non-standard record sometimes the cost-benifit of coding the
|
|
record by hand will be greater than attempting modify the
|
|
generator. The main point of the record generator is to save
|
|
time, so keep that in mind.
|
|
</p>
|
|
<p>
|
|
Currently the the XSL file that generates the record calls out to
|
|
Java objects. The Java code for the record generation is
|
|
currently quite messy with minimal comments.
|
|
</p>
|
|
</section>
|
|
</section>
|
|
</body>
|
|
</document>
|