| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== |
| --> |
| <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "../dtd/document-v11.dtd"> |
| |
| <document> |
| <header> |
| <title>Record Generator HOWTO</title> |
| <authors> |
| <person email="user@poi.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 HWPF. |
| See the HWPF 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> |