poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r681530 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/record/aggregates/ java/org/apache/poi/hssf/usermodel/ java/org/apache/poi/hssf/util/ testca...
Date Thu, 31 Jul 2008 22:44:49 GMT
Author: josh
Date: Thu Jul 31 15:44:48 2008
New Revision: 681530

URL: http://svn.apache.org/viewvc?rev=681530&view=rev
Log:
Fix for bug 45519 - keep data validation records together

Added:
    poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java
    poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
    poi/trunk/src/testcases/org/apache/poi/hssf/data/dvEmpty.xls   (with props)
Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java
    poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java
    poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
    poi/trunk/src/java/org/apache/poi/hssf/util/HSSFDataValidation.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Thu Jul 31 15:44:48 2008
@@ -37,6 +37,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.1.1-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
            <action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
            <action dev="POI-DEVELOPERS" type="add">45466 - Partial support for removing excel comments (won't work for all excel versions yet)</action>
            <action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Thu Jul 31 15:44:48 2008
@@ -34,6 +34,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.1.1-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>
            <action dev="POI-DEVELOPERS" type="add">Support for creating new HSLF CurrentUserAtoms</action>
            <action dev="POI-DEVELOPERS" type="add">45466 - Partial support for removing excel comments (won't work for all excel versions yet)</action>
            <action dev="POI-DEVELOPERS" type="fix">45437 - Detect encrypted word documents, and throw an EncryptedDocumentException instead of a OOM</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/RecordStream.java Thu Jul 31 15:44:48 2008
@@ -25,7 +25,7 @@
  *
  * @author Josh Micich
  */
-final class RecordStream {
+public final class RecordStream {
 
 	private final List _list;
 	private int _nextIndex;

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java Thu Jul 31 15:44:48 2008
@@ -17,13 +17,13 @@
 
 package org.apache.poi.hssf.model;
 
-import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.*; // normally I don't do this, buy we literally mean ALL
 import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
+import org.apache.poi.hssf.record.aggregates.DataValidityTable;
 import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
 import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
 import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate;
-import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.util.PaneInformation;
 
 import org.apache.poi.util.POILogFactory;
@@ -31,7 +31,7 @@
 
 import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.List;   // normally I don't do this, buy we literally mean ALL
+import java.util.List;   
 
 /**
  * Low level model implementation of a Sheet (one workbook contains many sheets)
@@ -90,6 +90,7 @@
     protected ProtectRecord              protect           =     null;
     protected PageBreakRecord            rowBreaks         =     null;
     protected PageBreakRecord            colBreaks         =     null;
+    private   DataValidityTable          _dataValidityTable=     null;
     protected ObjectProtectRecord        objprotect        =     null;
     protected ScenarioProtectRecord      scenprotect       =     null;
     protected PasswordRecord             password          =     null;
@@ -299,7 +300,12 @@
                 // and POI always re-calculates its contents 
                 rec = null;
             }
-
+            else if ( rec.getSid() == DVALRecord.sid) {
+                RecordStream rs = new RecordStream(recs, k);
+                retval._dataValidityTable = new DataValidityTable(rs);
+                k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based
+                rec = retval._dataValidityTable;
+            }
             else if ( rec.getSid() == ProtectRecord.sid )
             {
                 retval.protect = (ProtectRecord) rec;
@@ -425,56 +431,56 @@
         Sheet     retval  = new Sheet();
         ArrayList records = new ArrayList(30);
 
-        records.add(retval.createBOF());
+        records.add(createBOF());
 
         // records.add(retval.createIndex());
-        records.add(retval.createCalcMode());
-        records.add(retval.createCalcCount() );
-        records.add( retval.createRefMode() );
-        records.add( retval.createIteration() );
-        records.add( retval.createDelta() );
-        records.add( retval.createSaveRecalc() );
-        records.add( retval.createPrintHeaders() );
-        retval.printGridlines = (PrintGridlinesRecord) retval.createPrintGridlines();
+        records.add(createCalcMode());
+        records.add(createCalcCount() );
+        records.add(createRefMode() );
+        records.add(createIteration() );
+        records.add(createDelta() );
+        records.add(createSaveRecalc() );
+        records.add(createPrintHeaders() );
+        retval.printGridlines = createPrintGridlines();
         records.add( retval.printGridlines );
-        retval.gridset = (GridsetRecord) retval.createGridset();
+        retval.gridset = createGridset();
         records.add( retval.gridset );
         records.add( retval.createGuts() );
-        retval.defaultrowheight =
-                (DefaultRowHeightRecord) retval.createDefaultRowHeight();
+        retval.defaultrowheight = createDefaultRowHeight();
         records.add( retval.defaultrowheight );
         records.add( retval.createWSBool() );
-
+        
+        // 'Page Settings Block'
         retval.rowBreaks = new PageBreakRecord(PageBreakRecord.HORIZONTAL_SID);
         records.add(retval.rowBreaks);
         retval.colBreaks = new PageBreakRecord(PageBreakRecord.VERTICAL_SID);
         records.add(retval.colBreaks);
 
-        retval.header = (HeaderRecord) retval.createHeader();
+        retval.header = createHeader();
         records.add( retval.header );
-        retval.footer = (FooterRecord) retval.createFooter();
+        retval.footer = createFooter();
         records.add( retval.footer );
-        records.add( retval.createHCenter() );
-        records.add( retval.createVCenter() );
-        retval.printSetup = (PrintSetupRecord) retval.createPrintSetup();
+        records.add(createHCenter() );
+        records.add(createVCenter() );
+        retval.printSetup = createPrintSetup();
         records.add( retval.printSetup );
-        retval.defaultcolwidth =
-                (DefaultColWidthRecord) retval.createDefaultColWidth();
+
+        // 'Worksheet Protection Block' (after 'Page Settings Block' and before DEFCOLWIDTH)
+        // PROTECT record normally goes here, don't add yet since the flag is initially false
+        
+        retval.defaultcolwidth = createDefaultColWidth();
         records.add( retval.defaultcolwidth);
         ColumnInfoRecordsAggregate columns = new ColumnInfoRecordsAggregate();
         records.add( columns );
         retval.columns = columns;
-        retval.dims    = ( DimensionsRecord ) retval.createDimensions();
+        retval.dims    =  createDimensions();
         records.add(retval.dims);
         retval.dimsloc = records.size()-1;
         records.add(retval.windowTwo = retval.createWindowTwo());
         retval.setLoc(records.size() - 1);
-        retval.selection =
-                (SelectionRecord) retval.createSelection();
+        retval.selection = createSelection();
         records.add(retval.selection);
-        retval.protect = (ProtectRecord) retval.createProtect();
-        records.add(retval.protect);
-        records.add(retval.createEOF());
+        records.add(new EOFRecord());
 
 
         retval.records = records;
@@ -522,7 +528,7 @@
 
         if (merged == null || merged.getNumAreas() == 1027)
         {
-            merged = ( MergeCellsRecord ) createMergedCells();
+            merged = createMergedCells();
             mergedRecords.add(merged);
             records.add(records.size() - 1, merged);
         }
@@ -911,125 +917,12 @@
 
     /**
      * Create a row record.  (does not add it to the records contained in this sheet)
-     *
-     * @param row number
-     * @return RowRecord created for the passed in row number
-     * @see org.apache.poi.hssf.record.RowRecord
      */
-
-    public RowRecord createRow(int row)
-    {
+    private static RowRecord createRow(int row) {
         return RowRecordsAggregate.createRow( row );
     }
 
     /**
-     * Create a LABELSST Record (does not add it to the records contained in this sheet)
-     *
-     * @param row the row the LabelSST is a member of
-     * @param col the column the LabelSST defines
-     * @param index the index of the string within the SST (use workbook addSSTString method)
-     * @return LabelSSTRecord newly created containing your SST Index, row,col.
-     * @see org.apache.poi.hssf.record.SSTRecord
-     */
-    public LabelSSTRecord createLabelSST(int row, short col, int index)
-    {
-        log.logFormatted(POILogger.DEBUG, "create labelsst row,col,index %,%,%",
-                         new int[]
-        {
-            row, col, index
-        });
-        LabelSSTRecord rec = new LabelSSTRecord();
-
-        rec.setRow(row);
-        rec.setColumn(col);
-        rec.setSSTIndex(index);
-        rec.setXFIndex(( short ) 0x0f);
-        return rec;
-    }
-
-    /**
-     * Create a NUMBER Record (does not add it to the records contained in this sheet)
-     *
-     * @param row the row the NumberRecord is a member of
-     * @param col the column the NumberRecord defines
-     * @param value for the number record
-     *
-     * @return NumberRecord for that row, col containing that value as added to the sheet
-     */
-    public NumberRecord createNumber(int row, short col, double value)
-    {
-        log.logFormatted(POILogger.DEBUG, "create number row,col,value %,%,%",
-                         new double[]
-        {
-            row, col, value
-        });
-        NumberRecord rec = new NumberRecord();
-
-        rec.setRow(row);
-        rec.setColumn(col);
-        rec.setValue(value);
-        rec.setXFIndex(( short ) 0x0f);
-        return rec;
-    }
-
-    /**
-     * create a BLANK record (does not add it to the records contained in this sheet)
-     *
-     * @param row - the row the BlankRecord is a member of
-     * @param col - the column the BlankRecord is a member of
-     */
-    public BlankRecord createBlank(int row, short col)
-    {
-        log.logFormatted(POILogger.DEBUG, "create blank row,col %,%", new int[]
-        {
-            row, col
-        });
-        BlankRecord rec = new BlankRecord();
-
-        rec.setRow(row);
-        rec.setColumn(col);
-        rec.setXFIndex(( short ) 0x0f);
-        return rec;
-    }
-
-    /**
-     * Attempts to parse the formula into PTGs and create a formula record
-     * DOES NOT WORK YET
-     *
-     * @param row - the row for the formula record
-     * @param col - the column of the formula record
-     * @param formula - a String representing the formula.  To be parsed to PTGs
-     * @return bogus/useless formula record
-     */
-    public FormulaRecord createFormula(int row, short col, String formula)
-    {
-        log.logFormatted(POILogger.DEBUG, "create formula row,col,formula %,%,%",
-                         new int[]
-        {
-            row, col
-        }, formula);
-        FormulaRecord rec = new FormulaRecord();
-
-        rec.setRow(row);
-        rec.setColumn(col);
-        rec.setOptions(( short ) 2);
-        rec.setValue(0);
-        rec.setXFIndex(( short ) 0x0f);
-        FormulaParser fp = new FormulaParser(formula,null); //fix - do we need this method?
-        fp.parse();
-        Ptg[] ptg  = fp.getRPNPtg();
-        int   size = 0;
-
-        for (int k = 0; k < ptg.length; k++)
-        {
-            size += ptg[ k ].getSize();
-            rec.pushExpressionToken(ptg[ k ]);
-        }
-        rec.setExpressionLength(( short ) size);
-        return rec;
-    }
-
-    /**
      * Adds a value record to the sheet's contained binary records
      * (i.e. LabelSSTRecord or NumberRecord).
      * <P>
@@ -1247,13 +1140,8 @@
 
     /**
      * creates the BOF record
-     * @see org.apache.poi.hssf.record.BOFRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a BOFRecord
      */
-
-    protected Record createBOF()
-    {
+    private static BOFRecord createBOF() {
         BOFRecord retval = new BOFRecord();
 
         retval.setVersion(( short ) 0x600);
@@ -1267,30 +1155,9 @@
     }
 
     /**
-     * creates the Index record  - not currently used
-     * @see org.apache.poi.hssf.record.IndexRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a IndexRecord
-     */
-
-    protected Record createIndex()
-    {
-        IndexRecord retval = new IndexRecord();
-
-        retval.setFirstRow(0);   // must be set explicitly
-        retval.setLastRowAdd1(0);
-        return retval;
-    }
-
-    /**
      * creates the CalcMode record and sets it to 1 (automatic formula caculation)
-     * @see org.apache.poi.hssf.record.CalcModeRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a CalcModeRecord
      */
-
-    protected Record createCalcMode()
-    {
+    private static CalcModeRecord createCalcMode() {
         CalcModeRecord retval = new CalcModeRecord();
 
         retval.setCalcMode(( short ) 1);
@@ -1298,29 +1165,19 @@
     }
 
     /**
-     * creates the CalcCount record and sets it to 0x64 (default number of iterations)
-     * @see org.apache.poi.hssf.record.CalcCountRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a CalcCountRecord
+     * creates the CalcCount record and sets it to 100 (default number of iterations)
      */
-
-    protected Record createCalcCount()
-    {
+    private static CalcCountRecord createCalcCount() {
         CalcCountRecord retval = new CalcCountRecord();
 
-        retval.setIterations(( short ) 0x64);   // default 64 iterations
+        retval.setIterations(( short ) 100);   // default 100 iterations
         return retval;
     }
 
     /**
      * creates the RefMode record and sets it to A1 Mode (default reference mode)
-     * @see org.apache.poi.hssf.record.RefModeRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a RefModeRecord
      */
-
-    protected Record createRefMode()
-    {
+    private static RefModeRecord createRefMode() {
         RefModeRecord retval = new RefModeRecord();
 
         retval.setMode(RefModeRecord.USE_A1_MODE);
@@ -1329,13 +1186,8 @@
 
     /**
      * creates the Iteration record and sets it to false (don't iteratively calculate formulas)
-     * @see org.apache.poi.hssf.record.IterationRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a IterationRecord
      */
-
-    protected Record createIteration()
-    {
+    private static IterationRecord createIteration() {
         IterationRecord retval = new IterationRecord();
 
         retval.setIteration(false);
@@ -1344,13 +1196,8 @@
 
     /**
      * creates the Delta record and sets it to 0.0010 (default accuracy)
-     * @see org.apache.poi.hssf.record.DeltaRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a DeltaRecord
      */
-
-    protected Record createDelta()
-    {
+    private static DeltaRecord createDelta() {
         DeltaRecord retval = new DeltaRecord();
 
         retval.setMaxChange(0.0010);
@@ -1359,13 +1206,8 @@
 
     /**
      * creates the SaveRecalc record and sets it to true (recalculate before saving)
-     * @see org.apache.poi.hssf.record.SaveRecalcRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a SaveRecalcRecord
      */
-
-    protected Record createSaveRecalc()
-    {
+    private static SaveRecalcRecord createSaveRecalc() {
         SaveRecalcRecord retval = new SaveRecalcRecord();
 
         retval.setRecalc(true);
@@ -1374,13 +1216,8 @@
 
     /**
      * creates the PrintHeaders record and sets it to false (we don't create headers yet so why print them)
-     * @see org.apache.poi.hssf.record.PrintHeadersRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a PrintHeadersRecord
      */
-
-    protected Record createPrintHeaders()
-    {
+    private static PrintHeadersRecord createPrintHeaders() {
         PrintHeadersRecord retval = new PrintHeadersRecord();
 
         retval.setPrintHeaders(false);
@@ -1390,14 +1227,8 @@
     /**
      * creates the PrintGridlines record and sets it to false (that makes for ugly sheets).  As far as I can
      * tell this does the same thing as the GridsetRecord
-     *
-     * @see org.apache.poi.hssf.record.PrintGridlinesRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a PrintGridlinesRecord
      */
-
-    protected Record createPrintGridlines()
-    {
+    private static PrintGridlinesRecord createPrintGridlines() {
         PrintGridlinesRecord retval = new PrintGridlinesRecord();
 
         retval.setPrintGridlines(false);
@@ -1406,13 +1237,8 @@
 
     /**
      * creates the Gridset record and sets it to true (user has mucked with the gridlines)
-     * @see org.apache.poi.hssf.record.GridsetRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a GridsetRecord
      */
-
-    protected Record createGridset()
-    {
+    private static GridsetRecord createGridset() {
         GridsetRecord retval = new GridsetRecord();
 
         retval.setGridset(true);
@@ -1421,13 +1247,8 @@
 
     /**
      * creates the Guts record and sets leftrow/topcol guttter and rowlevelmax/collevelmax to 0
-     * @see org.apache.poi.hssf.record.GutsRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a GutsRecordRecord
-     */
-
-    protected Record createGuts()
-    {
+      */
+    private static GutsRecord createGuts() {
         GutsRecord retval = new GutsRecord();
 
         retval.setLeftRowGutter(( short ) 0);
@@ -1439,13 +1260,8 @@
 
     /**
      * creates the DefaultRowHeight Record and sets its options to 0 and rowheight to 0xff
-     * @see org.apache.poi.hssf.record.DefaultRowHeightRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a DefaultRowHeightRecord
      */
-
-    protected Record createDefaultRowHeight()
-    {
+    private static DefaultRowHeightRecord createDefaultRowHeight() {
         DefaultRowHeightRecord retval = new DefaultRowHeightRecord();
 
         retval.setOptionFlags(( short ) 0);
@@ -1455,13 +1271,8 @@
 
     /**
      * creates the WSBoolRecord and sets its values to defaults
-     * @see org.apache.poi.hssf.record.WSBoolRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a WSBoolRecord
      */
-
-    protected Record createWSBool()
-    {
+    private static WSBoolRecord createWSBool() {
         WSBoolRecord retval = new WSBoolRecord();
 
         retval.setWSBool1(( byte ) 0x4);
@@ -1471,13 +1282,8 @@
 
     /**
      * creates the Header Record and sets it to nothing/0 length
-     * @see org.apache.poi.hssf.record.HeaderRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a HeaderRecord
      */
-
-    protected Record createHeader()
-    {
+    private static HeaderRecord createHeader() {
         HeaderRecord retval = new HeaderRecord();
 
         retval.setHeaderLength(( byte ) 0);
@@ -1487,13 +1293,8 @@
 
     /**
      * creates the Footer Record and sets it to nothing/0 length
-     * @see org.apache.poi.hssf.record.FooterRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a FooterRecord
      */
-
-    protected Record createFooter()
-    {
+    private static FooterRecord createFooter() {
         FooterRecord retval = new FooterRecord();
 
         retval.setFooterLength(( byte ) 0);
@@ -1503,13 +1304,8 @@
 
     /**
      * creates the HCenter Record and sets it to false (don't horizontally center)
-     * @see org.apache.poi.hssf.record.HCenterRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a HCenterRecord
      */
-
-    protected Record createHCenter()
-    {
+    private static HCenterRecord createHCenter() {
         HCenterRecord retval = new HCenterRecord();
 
         retval.setHCenter(false);
@@ -1518,13 +1314,8 @@
 
     /**
      * creates the VCenter Record and sets it to false (don't horizontally center)
-     * @see org.apache.poi.hssf.record.VCenterRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a VCenterRecord
-     */
-
-    protected Record createVCenter()
-    {
+    */
+    private static VCenterRecord createVCenter() {
         VCenterRecord retval = new VCenterRecord();
 
         retval.setVCenter(false);
@@ -1537,9 +1328,7 @@
      * @see org.apache.poi.hssf.record.Record
      * @return record containing a PrintSetupRecord
      */
-
-    protected Record createPrintSetup()
-    {
+    private static PrintSetupRecord createPrintSetup() {
         PrintSetupRecord retval = new PrintSetupRecord();
 
         retval.setPaperSize(( short ) 1);
@@ -1558,31 +1347,14 @@
 
     /**
      * creates the DefaultColWidth Record and sets it to 8
-     * @see org.apache.poi.hssf.record.DefaultColWidthRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a DefaultColWidthRecord
-     */
-
-    protected Record createDefaultColWidth()
-    {
+      */
+    private static DefaultColWidthRecord createDefaultColWidth() {
         DefaultColWidthRecord retval = new DefaultColWidthRecord();
-
         retval.setColWidth(( short ) 8);
         return retval;
     }
 
     /**
-     * creates the ColumnInfo Record and sets it to a default column/width
-     * @see org.apache.poi.hssf.record.ColumnInfoRecord
-     * @return record containing a ColumnInfoRecord
-     */
-    // TODO change return type to ColumnInfoRecord 
-    protected Record createColInfo()
-    {
-        return ColumnInfoRecordsAggregate.createColInfo();
-    }
-
-    /**
      * get the default column width for the sheet (if the columns do not define their own width)
      * @return default column width
      */
@@ -1600,7 +1372,7 @@
     public boolean isGridsPrinted()
     {
         if (gridset == null) {
-            gridset = (GridsetRecord)createGridset();
+            gridset = createGridset();
             //Insert the newlycreated Gridset record at the end of the record (just before the EOF)
             int loc = findFirstRecordLocBySid(EOFRecord.sid);
             records.add(loc, gridset);
@@ -1816,22 +1588,18 @@
 
         GutsRecord guts = (GutsRecord) findFirstRecordBySid( GutsRecord.sid );
         guts.setColLevelMax( (short) ( maxLevel+1 ) );
-        if (maxLevel == 0)
+        if (maxLevel == 0) {
             guts.setTopColGutter( (short)0 );
-        else
+        } else {
             guts.setTopColGutter( (short) ( 29 + (12 * (maxLevel-1)) ) );
+        }
     }
 
     /**
      * creates the Dimensions Record and sets it to bogus values (you should set this yourself
      * or let the high level API do it for you)
-     * @see org.apache.poi.hssf.record.DimensionsRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a DimensionsRecord
      */
-
-    protected Record createDimensions()
-    {
+    private static DimensionsRecord createDimensions() {
         DimensionsRecord retval = new DimensionsRecord();
 
         retval.setFirstCol(( short ) 0);
@@ -1849,13 +1617,8 @@
      * headercolor    = 0x40 <P>
      * pagebreakzoom  = 0x0 <P>
      * normalzoom     = 0x0 <p>
-     * @see org.apache.poi.hssf.record.WindowTwoRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a WindowTwoRecord
      */
-
-    protected WindowTwoRecord createWindowTwo()
-    {
+    private static WindowTwoRecord createWindowTwo() {
         WindowTwoRecord retval = new WindowTwoRecord();
 
         retval.setOptions(( short ) 0x6b6);
@@ -1869,14 +1632,8 @@
 
     /**
      * Creates the Selection record and sets it to nothing selected
-     *
-     * @see org.apache.poi.hssf.record.SelectionRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a SelectionRecord
-     */
-
-    protected Record createSelection()
-    {
+    */
+    private static SelectionRecord createSelection() {
         SelectionRecord retval = new SelectionRecord();
 
         retval.setPane(( byte ) 0x3);
@@ -1903,19 +1660,15 @@
      * Sets the left column to show in desktop window pane.
      * @param leftCol the left column to show in desktop window pane
      */
-        public void setLeftCol(short leftCol){
-            if (windowTwo!=null)
-            {
+    public void setLeftCol(short leftCol){
+        if (windowTwo!=null) {
             windowTwo.setLeftCol(leftCol);
-            }
         }
+    }
 
-        public short getLeftCol()
-        {
-            return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol();
-        }
-
-
+    public short getLeftCol() {
+        return (windowTwo==null) ? (short) 0 : windowTwo.getLeftCol();
+    }
 
     /**
      * Returns the active row
@@ -1977,26 +1730,13 @@
         }
     }
 
-    protected Record createMergedCells()
-    {
+    private static  MergeCellsRecord createMergedCells() {
         MergeCellsRecord retval = new MergeCellsRecord();
         retval.setNumAreas(( short ) 0);
         return retval;
     }
 
     /**
-     * creates the EOF record
-     * @see org.apache.poi.hssf.record.EOFRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return record containing a EOFRecord
-     */
-
-    protected Record createEOF()
-    {
-        return new EOFRecord();
-    }
-
-    /**
      * get the location of the DimensionsRecord (which is the last record before the value section)
      * @return location in the array of records of the DimensionsRecord
      */
@@ -2383,28 +2123,20 @@
 
     /**
      * creates a Protect record with protect set to false.
-     * @see org.apache.poi.hssf.record.ProtectRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return a ProtectRecord
      */
-    protected Record createProtect()
-    {
-        if (log.check( POILogger.DEBUG ))
+    private static ProtectRecord createProtect() {
+        if (log.check( POILogger.DEBUG )) {
             log.log(POILogger.DEBUG, "create protect record with protection disabled");
-        ProtectRecord retval = new ProtectRecord();
-
-        retval.setProtect(false);
+        }
+        ProtectRecord retval = new ProtectRecord(); 
+        retval.setProtect(false); // TODO - supply param to constructor
         return retval;
     }
 
     /**
      * creates an ObjectProtect record with protect set to false.
-     * @see org.apache.poi.hssf.record.ObjectProtectRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return an ObjectProtectRecord
      */
-    protected ObjectProtectRecord createObjectProtect()
-    {
+    private static ObjectProtectRecord createObjectProtect() {
         if (log.check( POILogger.DEBUG ))
             log.log(POILogger.DEBUG, "create protect record with protection disabled");
         ObjectProtectRecord retval = new ObjectProtectRecord();
@@ -2415,12 +2147,8 @@
 
     /**
      * creates a ScenarioProtect record with protect set to false.
-     * @see org.apache.poi.hssf.record.ScenarioProtectRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return a ScenarioProtectRecord
      */
-    protected ScenarioProtectRecord createScenarioProtect()
-    {
+    private static ScenarioProtectRecord createScenarioProtect() {
         if (log.check( POILogger.DEBUG ))
             log.log(POILogger.DEBUG, "create protect record with protection disabled");
         ScenarioProtectRecord retval = new ScenarioProtectRecord();
@@ -2435,9 +2163,9 @@
     public ProtectRecord getProtect()
     {
         if (protect == null) {
-            protect = (ProtectRecord)createProtect();
-            //Insert the newlycreated protect record at the end of the record (just before the EOF)
-            int loc = findFirstRecordLocBySid(EOFRecord.sid);
+            protect = createProtect();
+            // Insert the newly created protect record just before DefaultColWidthRecord
+            int loc = findFirstRecordLocBySid(DefaultColWidthRecord.sid);
             records.add(loc, protect);
         }
         return protect;
@@ -2459,14 +2187,11 @@
 
     /**
      * creates a Password record with password set to 00.
-     * @see org.apache.poi.hssf.record.PasswordRecord
-     * @see org.apache.poi.hssf.record.Record
-     * @return a PasswordRecord
      */
-    protected PasswordRecord createPassword()
-    {
-        if (log.check( POILogger.DEBUG ))
-            log.log(POILogger.DEBUG, "create password record with 00 password");
+    private static PasswordRecord createPassword() {
+        if (log.check( POILogger.DEBUG )) {
+			log.log(POILogger.DEBUG, "create password record with 00 password");
+		}
         PasswordRecord retval = new PasswordRecord();
 
         retval.setPassword((short)00);
@@ -2892,4 +2617,10 @@
             rows.expandRow( row );
         }
     }
+    public DataValidityTable getOrCreateDataValidityTable() {
+        if (_dataValidityTable == null) {
+            _dataValidityTable = DataValidityTable.createForSheet(records);
+        }
+        return _dataValidityTable;
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java Thu Jul 31 15:44:48 2008
@@ -23,6 +23,7 @@
 
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.util.HSSFCellRangeAddress;
+import org.apache.poi.hssf.util.HSSFCellRangeAddress.AddrStructure;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.StringUtil;
@@ -114,7 +115,7 @@
     private BitField          opt_error_style                  = new BitField(0x00000070);
     private BitField          opt_string_list_formula          = new BitField(0x00000080);
     private BitField          opt_empty_cell_allowed           = new BitField(0x00000100);
-    private BitField          opt_surppres_dropdown_arrow      = new BitField(0x00000200);
+    private BitField          opt_suppress_dropdown_arrow      = new BitField(0x00000200);
     private BitField          opt_show_prompt_on_cell_selected = new BitField(0x00040000);
     private BitField          opt_show_error_on_invalid_value  = new BitField(0x00080000);
     private BitField          opt_condition_operator           = new BitField(0x00F00000);
@@ -283,25 +284,37 @@
     {
        return (this.opt_empty_cell_allowed.isSet(this.field_option_flags));
     }
+    /**
+     * @deprecated - (Jul-2008) use setSuppressDropDownArrow
+      */
+    public void setSurppresDropdownArrow(boolean suppress) {
+        setSuppressDropdownArrow(suppress);
+    }
+    /**
+     * @deprecated - (Jul-2008) use getSuppressDropDownArrow
+      */
+    public boolean getSurppresDropdownArrow() {
+        return getSuppressDropdownArrow();
+    }
 
     /**
-     * set if drop down arrow should be surppressed when list validation is used
-     * @param type - true if drop down arrow should be surppressed when list validation is used, false otherwise
+     * set if drop down arrow should be suppressed when list validation is used
+     * @param type - true if drop down arrow should be suppressed when list validation is used, false otherwise
      * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
      */
-    public void setSurppresDropdownArrow(boolean surppress)
+    public void setSuppressDropdownArrow(boolean suppress)
     {
-        this.field_option_flags =  this.opt_surppres_dropdown_arrow.setBoolean(this.field_option_flags, surppress);
+        this.field_option_flags =  this.opt_suppress_dropdown_arrow.setBoolean(this.field_option_flags, suppress);
     }
 
     /**
-     * return true if drop down arrow should be surppressed when list validation is used, false otherwise
-     * @return if drop down arrow should be surppressed when list validation is used, false otherwise
+     * return true if drop down arrow should be suppressed when list validation is used, false otherwise
+     * @return if drop down arrow should be suppressed when list validation is used, false otherwise
      * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
      */
-    public boolean getSurppresDropdownArrow()
+    public boolean getSuppressDropdownArrow()
     {
-       return (this.opt_surppres_dropdown_arrow.isSet(this.field_option_flags));
+       return (this.opt_suppress_dropdown_arrow.isSet(this.field_option_flags));
     }
 
     /**
@@ -433,9 +446,40 @@
     public String toString()
     {
       /** @todo DVRecord string representation */
-        StringBuffer buffer = new StringBuffer();
-
-        return buffer.toString();
+        StringBuffer sb = new StringBuffer();
+        sb.append("[DV]\n");
+        sb.append(" options=").append(Integer.toHexString(field_option_flags));
+        sb.append(" title-prompt=").append(field_title_prompt);
+        sb.append(" title-error=").append(field_title_error);
+        sb.append(" text-prompt=").append(field_text_prompt);
+        sb.append(" text-error=").append(field_text_error);
+        sb.append("\n");
+        appendFormula(sb, "Formula 1:",  field_rpn_token_1);
+        appendFormula(sb, "Formula 2:",  field_rpn_token_2);
+        int nRegions = field_regions.getADDRStructureNumber();
+        for(int i=0; i<nRegions; i++) {
+            AddrStructure addr = field_regions.getADDRStructureAt(i);
+            sb.append('(').append(addr.getFirstRow()).append(',').append(addr.getLastRow());
+            sb.append(',').append(addr.getFirstColumn()).append(',').append(addr.getLastColumn()).append(')');
+        }
+        sb.append("\n");
+        sb.append("[/DV]");
+
+        return sb.toString();
+    }
+
+    private void appendFormula(StringBuffer sb, String label, Stack stack) {
+        sb.append(label);
+        if (stack.isEmpty()) {
+            sb.append("<empty>\n");
+            return;
+        }
+        sb.append("\n");
+        Ptg[] ptgs = new Ptg[stack.size()];
+        stack.toArray(ptgs);
+        for (int i = 0; i < ptgs.length; i++) {
+            sb.append('\t').append(ptgs[i].toString()).append('\n');
+        }
     }
 
     public int serialize(int offset, byte [] data)
@@ -506,7 +550,7 @@
      *  contents are somewhat complex
      */
     public Object clone() {
-    	return cloneViaReserialise();
+        return cloneViaReserialise();
     }
 
     /**@todo DVRecord = Serializare */
@@ -535,7 +579,7 @@
             this._string_unicode_flag = in.readByte(); 
             if (this._string_unicode_flag == 1)
             {
-            	this._string_data = in.readUnicodeLEString(this._string_length);
+                this._string_data = in.readUnicodeLEString(this._string_length);
             }
             else
             {

Added: poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java?rev=681530&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/DataValidityTable.java Thu Jul 31 15:44:48 2008
@@ -0,0 +1,240 @@
+/* ====================================================================
+   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.
+==================================================================== */
+
+package org.apache.poi.hssf.record.aggregates;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.poi.hssf.model.FormulaParser;
+import org.apache.poi.hssf.model.RecordStream;
+import org.apache.poi.hssf.record.CFHeaderRecord;
+import org.apache.poi.hssf.record.CFRuleRecord;
+import org.apache.poi.hssf.record.DVALRecord;
+import org.apache.poi.hssf.record.DVRecord;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.HyperlinkRecord;
+import org.apache.poi.hssf.record.MergeCellsRecord;
+import org.apache.poi.hssf.record.PaneRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.SelectionRecord;
+import org.apache.poi.hssf.record.WindowTwoRecord;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.util.HSSFCellRangeAddress;
+import org.apache.poi.hssf.util.HSSFDataValidation;
+
+/**
+ * Manages the DVALRecord and DVRecords for a single sheet<br/>
+ * See OOO excelfileformat.pdf section 4.14
+ * @author Josh Micich
+ */
+public final class DataValidityTable extends RecordAggregate {
+
+	private static final short sid = -0x01B2; // not a real record
+	private final DVALRecord _headerRec;
+	/**
+	 * The list of data validations for the current sheet.
+	 * Note - this may be empty (contrary to OOO documentation)
+	 */
+	private final List _validationList;
+
+	public DataValidityTable(RecordStream rs) {
+		_headerRec = (DVALRecord) rs.getNext();
+		List temp = new ArrayList();
+		while (rs.peekNextClass() == DVRecord.class) {
+			temp.add(rs.getNext());
+		}
+		_validationList = temp;
+	}
+
+	private DataValidityTable() {
+		_headerRec = new DVALRecord();
+		_validationList = new ArrayList();
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	public int serialize(int offset, byte[] data) {
+		int result = _headerRec.serialize(offset, data);
+		for (int i = 0; i < _validationList.size(); i++) {
+			result += ((Record) _validationList.get(i)).serialize(offset + result, data);
+		}
+		return result;
+	}
+
+	public int getRecordSize() {
+		int result = _headerRec.getRecordSize();
+		for (int i = _validationList.size() - 1; i >= 0; i--) {
+			result += ((Record) _validationList.get(i)).getRecordSize();
+		}
+		return result;
+	}
+
+	/**
+	 * Creates a new <tt>DataValidityTable</tt> and inserts it in the right
+	 * place in the sheetRecords list.
+	 */
+	public static DataValidityTable createForSheet(List sheetRecords) {
+		int index = findDVTableInsertPos(sheetRecords);
+
+		DataValidityTable result = new DataValidityTable();
+		sheetRecords.add(index, result);
+		return result;
+	}
+	
+    /**
+     * Finds the index where the sheet validations header record should be inserted
+     * @param records the records for this sheet
+     * 
+     * + WINDOW2
+     * o SCL
+     * o PANE
+     * oo SELECTION
+     * o STANDARDWIDTH
+     * oo MERGEDCELLS
+     * o LABELRANGES
+     * o PHONETICPR
+     * o Conditional Formatting Table
+     * o Hyperlink Table
+     * o Data Validity Table
+     * o SHEETLAYOUT
+     * o SHEETPROTECTION
+     * o RANGEPROTECTION
+     * + EOF
+     */
+    private static int findDVTableInsertPos(List records) {
+		int i = records.size() - 1;
+		if (!(records.get(i) instanceof EOFRecord)) {
+			throw new IllegalStateException("Last sheet record should be EOFRecord");
+		}
+		while (i > 0) {
+			i--;
+			Record rec = (Record) records.get(i);
+			if (isPriorRecord(rec.getSid())) {
+				Record nextRec = (Record) records.get(i + 1);
+				if (!isSubsequentRecord(nextRec.getSid())) {
+					throw new IllegalStateException("Unexpected (" + nextRec.getClass().getName()
+							+ ") found after (" + rec.getClass().getName() + ")");
+				}
+				return i;
+			}
+			if (!isSubsequentRecord(rec.getSid())) {
+				throw new IllegalStateException("Unexpected (" + rec.getClass().getName()
+						+ ") while looking for DV Table insert pos");
+			}
+		}
+		return 0;
+	}
+
+	// TODO - add UninterpretedRecord as base class for many of these
+	// unimplemented sids
+
+	private static boolean isPriorRecord(short sid) {
+		switch(sid) {
+			case WindowTwoRecord.sid:
+			case 0x00A0: // SCL
+			case PaneRecord.sid:
+			case SelectionRecord.sid:
+			case 0x0099: // STANDARDWIDTH
+			case MergeCellsRecord.sid:
+			case 0x015F: // LABELRANGES
+			case 0x00EF: // PHONETICPR
+			case CFHeaderRecord.sid:
+			case CFRuleRecord.sid:
+			case HyperlinkRecord.sid:
+			case 0x0800: // QUICKTIP
+				return true;
+		}
+		return false;
+	}
+
+	private static boolean isSubsequentRecord(short sid) {
+		switch(sid) {
+			case 0x0862: // SHEETLAYOUT
+			case 0x0867: // SHEETPROTECTION
+			case 0x0868: // RANGEPROTECTION
+			case EOFRecord.sid:
+				return true;
+		}
+		return false;
+	}
+
+	public void addDataValidation(HSSFDataValidation dataValidation, HSSFWorkbook workbook) {
+
+		DVRecord dvRecord = new DVRecord();
+
+		// dv record's option flags
+		dvRecord.setDataType(dataValidation.getDataValidationType());
+		dvRecord.setErrorStyle(dataValidation.getErrorStyle());
+		dvRecord.setEmptyCellAllowed(dataValidation.getEmptyCellAllowed());
+		dvRecord.setSuppressDropdownArrow(dataValidation.getSuppressDropDownArrow());
+		dvRecord.setShowPromptOnCellSelected(dataValidation.getShowPromptBox());
+		dvRecord.setShowErrorOnInvalidValue(dataValidation.getShowErrorBox());
+		dvRecord.setConditionOperator(dataValidation.getOperator());
+
+		// string fields
+		dvRecord.setStringField(DVRecord.STRING_PROMPT_TITLE, dataValidation.getPromptBoxTitle());
+		dvRecord.setStringField(DVRecord.STRING_PROMPT_TEXT, dataValidation.getPromptBoxText());
+		dvRecord.setStringField(DVRecord.STRING_ERROR_TITLE, dataValidation.getErrorBoxTitle());
+		dvRecord.setStringField(DVRecord.STRING_ERROR_TEXT, dataValidation.getErrorBoxText());
+
+		// formula fields ( size and data )
+		Stack ptg_arr = new Stack();
+		Ptg[] ptg = FormulaParser.parse(dataValidation.getFirstFormula(), workbook);
+		int size = 0;
+		for (int k = 0; k < ptg.length; k++) {
+			if (ptg[k] instanceof org.apache.poi.hssf.record.formula.AreaPtg) {
+				// we should set ptgClass to Ptg.CLASS_REF and explicit formula
+				// string to false
+				// ptg[k].setClass(Ptg.CLASS_REF);
+				// obj_validation.setExplicitListFormula(false);
+			}
+			size += ptg[k].getSize();
+			ptg_arr.push(ptg[k]);
+		}
+		dvRecord.setFirstFormulaRPN(ptg_arr);
+		dvRecord.setFirstFormulaSize((short) size);
+
+		dvRecord.setListExplicitFormula(dataValidation.getExplicitListFormula());
+
+		if (dataValidation.getSecondFormula() != null) {
+
+			ptg_arr = new Stack();
+			ptg = FormulaParser.parse(dataValidation.getSecondFormula(), workbook);
+			size = 0;
+			for (int k = 0; k < ptg.length; k++) {
+				size += ptg[k].getSize();
+				ptg_arr.push(ptg[k]);
+			}
+			dvRecord.setSecFormulaRPN(ptg_arr);
+			dvRecord.setSecFormulaSize((short) size);
+		}
+
+		// dv records cell range field
+		HSSFCellRangeAddress cell_range = new HSSFCellRangeAddress();
+		cell_range.addADDRStructure(dataValidation.getFirstRow(), dataValidation.getFirstColumn(),
+				dataValidation.getLastRow(), dataValidation.getLastColumn());
+		dvRecord.setCellRangeAddress(cell_range);
+
+		_validationList.add(dvRecord);
+		_headerRec.setDVRecNo(_validationList.size());
+	}
+}

Added: poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java?rev=681530&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java Thu Jul 31 15:44:48 2008
@@ -0,0 +1,41 @@
+/* ====================================================================
+   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.
+==================================================================== */
+
+package org.apache.poi.hssf.record.aggregates;
+
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * <tt>RecordAggregate</tt>s are groups of of BIFF <tt>Record</tt>s that are typically stored 
+ * together and/or updated together.  Workbook / Sheet records are typically stored in a sequential
+ * list, which does not provide much structure to coordinate updates.
+ * 
+ * @author Josh Micich
+ */
+public abstract class RecordAggregate extends Record {
+	// TODO - convert existing aggregate classes to proper subclasses of this one
+	protected final void validateSid(short id) {
+		// TODO - break class hierarchy and make separate from Record
+		throw new RuntimeException("Should not be called");
+	}
+	protected final void fillFields(RecordInputStream in) {
+		throw new RuntimeException("Should not be called");
+	}
+	// force subclassses to provide better implementation than default
+	public abstract int getRecordSize();
+}

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Thu Jul 31 15:44:48 2008
@@ -28,7 +28,6 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Stack;
 import java.util.TreeMap;
 
 import org.apache.poi.ddf.EscherRecord;
@@ -36,9 +35,9 @@
 import org.apache.poi.hssf.model.Sheet;
 import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.aggregates.DataValidityTable;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.util.HSSFCellRangeAddress;
 import org.apache.poi.hssf.util.HSSFDataValidation;
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.hssf.util.Region;
@@ -375,92 +374,18 @@
 
     /**
      * Creates a data validation object
-     * @param obj_validation The Data validation object settings
+     * @param dataValidation The Data validation object settings
      */
-    public void addValidationData(HSSFDataValidation obj_validation)
-    {
-       if ( obj_validation == null )
-       {
-         return;
-       }
-       DVALRecord dvalRec = (DVALRecord)sheet.findFirstRecordBySid( DVALRecord.sid );
-       int eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
-       if ( dvalRec == null )
-       {
-          dvalRec = new DVALRecord();
-          sheet.getRecords().add( eofLoc, dvalRec );
-       }
-       int curr_dvRecNo = dvalRec.getDVRecNo();
-       dvalRec.setDVRecNo(curr_dvRecNo+1);
-
-       //create dv record
-       DVRecord dvRecord = new DVRecord();
-
-       //dv record's option flags
-       dvRecord.setDataType( obj_validation.getDataValidationType() );
-       dvRecord.setErrorStyle(obj_validation.getErrorStyle());
-       dvRecord.setEmptyCellAllowed(obj_validation.getEmptyCellAllowed());
-       dvRecord.setSurppresDropdownArrow(obj_validation.getSurppressDropDownArrow());
-       dvRecord.setShowPromptOnCellSelected(obj_validation.getShowPromptBox());
-       dvRecord.setShowErrorOnInvalidValue(obj_validation.getShowErrorBox());
-       dvRecord.setConditionOperator(obj_validation.getOperator());
-
-       //string fields
-       dvRecord.setStringField( DVRecord.STRING_PROMPT_TITLE,obj_validation.getPromptBoxTitle());
-       dvRecord.setStringField( DVRecord.STRING_PROMPT_TEXT, obj_validation.getPromptBoxText());
-       dvRecord.setStringField( DVRecord.STRING_ERROR_TITLE, obj_validation.getErrorBoxTitle());
-       dvRecord.setStringField( DVRecord.STRING_ERROR_TEXT, obj_validation.getErrorBoxText());
-
-       //formula fields ( size and data )
-       String str_formula = obj_validation.getFirstFormula();
-       FormulaParser fp = new FormulaParser(str_formula, workbook);
-       fp.parse();
-       Stack ptg_arr = new Stack();
-       Ptg[] ptg  = fp.getRPNPtg();
-       int size = 0;
-       for (int k = 0; k < ptg.length; k++)
-       {
-           if ( ptg[k] instanceof org.apache.poi.hssf.record.formula.AreaPtg )
-           {
-              //we should set ptgClass to Ptg.CLASS_REF and explicit formula string to false
-              ptg[k].setClass(Ptg.CLASS_REF);
-              obj_validation.setExplicitListFormula(false);
-           }
-           size += ptg[k].getSize();
-           ptg_arr.push(ptg[k]);
+    public void addValidationData(HSSFDataValidation dataValidation) {
+       if (dataValidation == null) {
+           throw new IllegalArgumentException("objValidation must not be null");
        }
-       dvRecord.setFirstFormulaRPN(ptg_arr);
-       dvRecord.setFirstFormulaSize((short)size);
+       DataValidityTable dvt = sheet.getOrCreateDataValidityTable();
 
-       dvRecord.setListExplicitFormula(obj_validation.getExplicitListFormula());
-
-       if ( obj_validation.getSecondFormula() != null )
-       {
-         str_formula = obj_validation.getSecondFormula();
-         fp = new FormulaParser(str_formula, workbook);
-         fp.parse();
-         ptg_arr = new Stack();
-         ptg  = fp.getRPNPtg();
-         size = 0;
-         for (int k = 0; k < ptg.length; k++)
-         {
-             size += ptg[k].getSize();
-             ptg_arr.push(ptg[k]);
-         }
-         dvRecord.setSecFormulaRPN(ptg_arr);
-         dvRecord.setSecFormulaSize((short)size);
-       }
-
-       //dv records cell range field
-       HSSFCellRangeAddress cell_range = new HSSFCellRangeAddress();
-       cell_range.addADDRStructure(obj_validation.getFirstRow(), obj_validation.getFirstColumn(), obj_validation.getLastRow(), obj_validation.getLastColumn());
-       dvRecord.setCellRangeAddress(cell_range);
-
-       //add dv record
-       eofLoc = sheet.findFirstRecordLocBySid( EOFRecord.sid );
-       sheet.getRecords().add( eofLoc, dvRecord );
+       dvt.addDataValidation(dataValidation, workbook);
     }
 
+
     /**
      * Get the visibility state for a given column.
      * @param column - the column to get (0-based)

Modified: poi/trunk/src/java/org/apache/poi/hssf/util/HSSFDataValidation.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/util/HSSFDataValidation.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/util/HSSFDataValidation.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/util/HSSFDataValidation.java Thu Jul 31 15:44:48 2008
@@ -218,13 +218,25 @@
   {
      return this._empty_cell_allowed ;
   }
+  /**
+   * @deprecated - (Jul-2008) use setSuppressDropDownArrow
+    */
+  public void setSurppressDropDownArrow( boolean suppress ) {
+    setSuppressDropDownArrow(suppress);
+  }
+  /**
+   * @deprecated - (Jul-2008) use getSuppressDropDownArrow
+    */
+  public boolean getSurppressDropDownArrow( ) {
+    return getSuppressDropDownArrow();
+  }
 
   /**
    * Useful for list validation objects .
    * @param surppres True if a list should display the values into a drop down list , false otherwise .
    *                 In other words , if a list should display the arrow sign on its right side
    */
-  public void setSurppressDropDownArrow( boolean surppres )
+  public void setSuppressDropDownArrow( boolean surppres )
   {
      this._surpress_dropdown_arrow = surppres;
   }
@@ -235,7 +247,7 @@
    * @return True if a list should display the values into a drop down list , false otherwise .
    * @see setDataValidationType( int data_type )
    */
-  public boolean getSurppressDropDownArrow( )
+  public boolean getSuppressDropDownArrow( )
   {
      if ( this._data_type != HSSFDataValidation.DATA_TYPE_LIST )
      {

Added: poi/trunk/src/testcases/org/apache/poi/hssf/data/dvEmpty.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/dvEmpty.xls?rev=681530&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/testcases/org/apache/poi/hssf/data/dvEmpty.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java Thu Jul 31 15:44:48 2008
@@ -297,7 +297,8 @@
         xfindex = sheet.getXFIndexForColAt((short) 1);
         assertEquals(DEFAULT_IDX, xfindex);
 
-        ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo();
+        // TODO change return type to ColumnInfoRecord 
+        ColumnInfoRecord nci = (ColumnInfoRecord)ColumnInfoRecordsAggregate.createColInfo();
         sheet.columns.insertColumn(nci);
 
         // single column ColumnInfoRecord

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheetAdditional.java Thu Jul 31 15:44:48 2008
@@ -17,13 +17,10 @@
 
 package org.apache.poi.hssf.model;
 
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.ColumnInfoRecord;
+import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;
 
 /**
  * @author Tony Poppleton
@@ -32,7 +29,8 @@
 	
 	public void testGetCellWidth() {
 		Sheet sheet = Sheet.createSheet();
-		ColumnInfoRecord nci = ( ColumnInfoRecord ) sheet.createColInfo();
+		// TODO change return type to ColumnInfoRecord 
+		ColumnInfoRecord nci = (ColumnInfoRecord)ColumnInfoRecordsAggregate.createColInfo();
 
 		// Prepare test model
 		nci.setFirstColumn((short)5);

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java?rev=681530&r1=681529&r2=681530&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java Thu Jul 31 15:44:48 2008
@@ -16,13 +16,25 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import junit.framework.TestCase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
 
-import org.apache.poi.hssf.util.*;
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
 
-import java.io.*;
-import java.util.*;
-import java.text.SimpleDateFormat;
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.eventmodel.ERFListener;
+import org.apache.poi.hssf.eventmodel.EventRecordFactory;
+import org.apache.poi.hssf.record.DVRecord;
+import org.apache.poi.hssf.record.RecordFormatException;
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.hssf.util.HSSFDataValidation;
+import org.apache.poi.hssf.util.Region;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 
 /**
  * <p>Title: TestDataValidation</p>
@@ -34,19 +46,6 @@
  */
 public class TestDataValidation extends TestCase
 {
-  public TestDataValidation(String name)
-  {
-    super(name);
-  }
-
-  protected void setUp()
-  {
-    String filename = System.getProperty("HSSF.testdata.path");
-    if (filename == null)
-    {
-       System.setProperty("HSSF.testdata.path", "src/testcases/org/apache/poi/hssf/data");
-    }
-  }
 
   public void testDataValidation() throws Exception
   {
@@ -903,8 +902,88 @@
      cell.setCellValue(strStettings);
   }
 
-  public static void main(String[] args)
-  {
-    junit.textui.TestRunner.run(TestDataValidation.class);
-  }
+  
+	public void testAddToExistingSheet() {
+
+		// dvEmpty.xls is a simple one sheet workbook.  With a DataValidations header record but no 
+		// DataValidations.  It's important that the example has one SHEETPROTECTION record.
+		// Such a workbook can be created in Excel (2007) by adding datavalidation for one cell
+		// and then deleting the row that contains the cell.
+		HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("dvEmpty.xls");  
+		int dvRow = 0;
+		HSSFSheet sheet = wb.getSheetAt(0);
+		sheet.createRow(dvRow).createCell((short)0);
+		HSSFDataValidation dv = new HSSFDataValidation((short)dvRow, (short)0, (short)dvRow, (short)0);
+		
+		dv.setDataValidationType(HSSFDataValidation.DATA_TYPE_INTEGER);
+		dv.setEmptyCellAllowed(false);
+		dv.setOperator(HSSFDataValidation.OPERATOR_EQUAL);
+		dv.setFirstFormula("42");
+		dv.setErrorStyle(HSSFDataValidation.ERROR_STYLE_STOP);
+		dv.setShowPromptBox(true);
+		dv.createErrorBox("Error", "The value is wrong");
+		dv.setSurppressDropDownArrow(true);
+
+		sheet.addValidationData(dv);
+		wb.toString();
+		
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		try {
+			wb.write(baos);
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		
+		byte[] wbData = baos.toByteArray();
+		
+		if (false) { // TODO (Jul 2008) fix EventRecordFactory to process unknown records, (and DV records for that matter)
+			EventRecordFactory erf = new EventRecordFactory();
+			ERFListener erfListener = null; // new MyERFListener();
+			erf.registerListener(erfListener, null);
+			try {
+				POIFSFileSystem fs = new POIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
+				erf.processRecords(fs.createDocumentInputStream("Workbook"));
+			} catch (RecordFormatException e) {
+				throw new RuntimeException(e);
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+		// else verify record ordering by navigating the raw bytes
+		
+		byte[] dvHeaderRecStart= { (byte)0xB2, 0x01, 0x12, 0x00, };
+		int dvHeaderOffset = findIndex(wbData, dvHeaderRecStart);
+		assertTrue(dvHeaderOffset > 0);
+		int nextRecIndex = dvHeaderOffset + 22;
+		int nextSid 
+			= ((wbData[nextRecIndex + 0] << 0) & 0x00FF) 
+			+ ((wbData[nextRecIndex + 1] << 8) & 0xFF00)
+			;
+		// nextSid should be for a DVRecord.  If anything comes between the DV header record 
+		// and the DV records, Excel will not be able to open the workbook without error.
+		
+		if (nextSid == 0x0867) {
+			throw new AssertionFailedError("Identified bug XXXX");
+		}
+		assertEquals(DVRecord.sid, nextSid);
+	}
+	private int findIndex(byte[] largeData, byte[] searchPattern) {
+		byte firstByte = searchPattern[0];
+		for (int i = 0; i < largeData.length; i++) {
+			if(largeData[i] != firstByte) {
+				continue;
+			}
+			boolean match = true;
+			for (int j = 1; j < searchPattern.length; j++) {
+				if(searchPattern[j] != largeData[i+j]) {
+					match = false;
+					break;
+				}
+			}
+			if (match) {
+				return i;
+			}
+		}
+		return -1;
+	}
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message