You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/05/23 11:48:28 UTC

svn commit: r659485 [1/3] - in /poi/branches/ooxml: ./ src/documentation/content/xdocs/ src/examples/src/org/apache/poi/hslf/ src/examples/src/org/apache/poi/hslf/usermodel/ src/examples/src/org/apache/poi/hslf/usermodel/examples/ src/java/org/apache/p...

Author: nick
Date: Fri May 23 02:48:23 2008
New Revision: 659485

URL: http://svn.apache.org/viewvc?rev=659485&view=rev
Log:
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,
 649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-659484 via svnmerge from 
https://svn.apache.org:443/repos/asf/poi/trunk

........
  r658322 | nick | 2008-05-20 17:37:15 +0100 (Tue, 20 May 2008) | 1 line
  
  Fix bug #44977 - Support for AM/PM in excel date formats
........
  r658336 | nick | 2008-05-20 17:51:49 +0100 (Tue, 20 May 2008) | 1 line
  
  Test which seems to show that bug #44996 is invalid, but not completely sure
........
  r658349 | nick | 2008-05-20 17:57:20 +0100 (Tue, 20 May 2008) | 1 line
  
  Patch from bug #45001 - Partial fix for HWPF Range.insertBefore() and Range.delete() with unicode characters
........
  r658350 | nick | 2008-05-20 18:12:08 +0100 (Tue, 20 May 2008) | 1 line
  
  Put abstract write(OutputStream) method on POIDocument
........
  r658352 | nick | 2008-05-20 18:17:16 +0100 (Tue, 20 May 2008) | 1 line
  
  Patch from bug #45003 - Support embeded HDGF visio documents
........
  r658833 | josh | 2008-05-21 20:57:40 +0100 (Wed, 21 May 2008) | 1 line
  
  improved toString and refactored toFormulaString on Area(3D)Ptg
........
  r658984 | josh | 2008-05-22 04:00:29 +0100 (Thu, 22 May 2008) | 1 line
  
  Fixed compiler errors.  Other improvements for type safety and immutability.
........
  r658986 | josh | 2008-05-22 04:26:25 +0100 (Thu, 22 May 2008) | 1 line
  
  Follow on from bug 44675 - regenerated functionMetadata.txt from new ooo excelfileformat.odt
........
  r659067 | nick | 2008-05-22 10:51:44 +0100 (Thu, 22 May 2008) | 1 line
  
  Example for finding hslf sounds from Yegor
........
  r659403 | josh | 2008-05-23 04:56:31 +0100 (Fri, 23 May 2008) | 1 line
  
  Fix for 45066 - sheet encoding size mismatch problems
........
  r659429 | josh | 2008-05-23 06:28:54 +0100 (Fri, 23 May 2008) | 1 line
  
  Fix for bug 45046 - allowed DEFINEDNAME records without EXTERNALBOOK records
........
  r659452 | josh | 2008-05-23 07:43:51 +0100 (Fri, 23 May 2008) | 1 line
  
  Bug 45041 - improved FormulaParser parse error messages
........
  r659455 | josh | 2008-05-23 07:54:46 +0100 (Fri, 23 May 2008) | 1 line
  
  Bug 45025 - improved FormulaParser parse error messages (r659452 had wrong bug number)
........
  r659462 | josh | 2008-05-23 08:42:14 +0100 (Fri, 23 May 2008) | 1 line
  
  Marked out test failure which was fixed by patch for bug 39903
........
  r659478 | josh | 2008-05-23 09:55:48 +0100 (Fri, 23 May 2008) | 1 line
  
  Fix for bug 35925 - Missing HSSFColor.TAN from HashTables returned by getIndexHash() and getTripletHash()
........

Added:
    poi/branches/ooxml/src/examples/src/org/apache/poi/hslf/
      - copied from r659478, poi/trunk/src/examples/src/org/apache/poi/hslf/
    poi/branches/ooxml/src/examples/src/org/apache/poi/hslf/usermodel/
      - copied from r659478, poi/trunk/src/examples/src/org/apache/poi/hslf/usermodel/
    poi/branches/ooxml/src/examples/src/org/apache/poi/hslf/usermodel/examples/
      - copied from r659478, poi/trunk/src/examples/src/org/apache/poi/hslf/usermodel/examples/
    poi/branches/ooxml/src/examples/src/org/apache/poi/hslf/usermodel/examples/SoundFinder.java
      - copied unchanged from r659478, poi/trunk/src/examples/src/org/apache/poi/hslf/usermodel/examples/SoundFinder.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/data/ex45046-21984.xls
      - copied unchanged from r659478, poi/trunk/src/testcases/org/apache/poi/hssf/data/ex45046-21984.xls
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestLinkTable.java
      - copied unchanged from r659478, poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestLinkTable.java
Modified:
    poi/branches/ooxml/   (props changed)
    poi/branches/ooxml/build.xml
    poi/branches/ooxml/src/documentation/content/xdocs/changes.xml
    poi/branches/ooxml/src/documentation/content/xdocs/status.xml
    poi/branches/ooxml/src/java/org/apache/poi/POIDocument.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/model/FormulaParser.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/model/LinkTable.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Sheet.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/record/DBCellRecord.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/util/AreaReference.java
    poi/branches/ooxml/src/java/org/apache/poi/hssf/util/HSSFColor.java
    poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/DateUtil.java
    poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt
    poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hwpf/model/FSPATable.java
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hwpf/model/TextPiece.java
    poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/model/TestSheet.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/function/ExcelFileFormatDocFunctionExtractor.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/function/TestParseMissingBuiltInFuncs.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/record/formula/function/TestReadMissingBuiltInFuncs.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java
    poi/branches/ooxml/src/testcases/org/apache/poi/hssf/usermodel/TestSheetHiding.java

Propchange: poi/branches/ooxml/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri May 23 02:48:23 2008
@@ -1 +1 @@
-/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-658312
+/poi/trunk:1-638784,638786-639486,639488-639601,639603-640056,640058-642562,642564-642566,642568-642574,642576-642736,642739-650914,650916-659484

Modified: poi/branches/ooxml/build.xml
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/build.xml?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/build.xml (original)
+++ poi/branches/ooxml/build.xml Fri May 23 02:48:23 2008
@@ -245,6 +245,7 @@
     <path id="examples.classpath">
         <path refid="main.classpath"/>
         <pathelement location="${main.output.dir}"/>
+        <pathelement location="${scratchpad.output.dir}"/>
     </path>
 
 

Modified: poi/branches/ooxml/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/documentation/content/xdocs/changes.xml?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/documentation/content/xdocs/changes.xml (original)
+++ poi/branches/ooxml/src/documentation/content/xdocs/changes.xml Fri May 23 02:48:23 2008
@@ -44,6 +44,12 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1-final" date="2008-06-??">
+           <action dev="POI-DEVELOPERS" type="add">45025 - improved FormulaParser parse error messages</action>
+           <action dev="POI-DEVELOPERS" type="add">45046 - allowed EXTERNALBOOK(0x01AE) to be optional in the LinkTable</action>
+           <action dev="POI-DEVELOPERS" type="add">45066 - fixed sheet encoding size mismatch problems</action>
+           <action dev="POI-DEVELOPERS" type="add">45003 - Support embeded HDGF visio documents</action>
+           <action dev="POI-DEVELOPERS" type="fix">45001 - Partial fix for HWPF Range.insertBefore() and Range.delete() with unicode characters</action>
+           <action dev="POI-DEVELOPERS" type="fix">44977 - Support for AM/PM in excel date formats</action>
            <action dev="POI-DEVELOPERS" type="add">Support for specifying a policy to HSSF on missing / blank cells when fetching</action>
            <action dev="POI-DEVELOPERS" type="add">44937 - Partial support for extracting Escher images from HWPF files</action>
            <action dev="POI-DEVELOPERS" type="fix">44824 - Avoid an infinite loop when reading some HWPF pictures</action>

Modified: poi/branches/ooxml/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/documentation/content/xdocs/status.xml?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/documentation/content/xdocs/status.xml (original)
+++ poi/branches/ooxml/src/documentation/content/xdocs/status.xml Fri May 23 02:48:23 2008
@@ -41,6 +41,12 @@
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1-final" date="2008-06-??">
+           <action dev="POI-DEVELOPERS" type="add">45025 - improved FormulaParser parse error messages</action>
+           <action dev="POI-DEVELOPERS" type="add">45046 - allowed EXTERNALBOOK(0x01AE) to be optional in the LinkTable</action>
+           <action dev="POI-DEVELOPERS" type="add">45066 - fixed sheet encoding size mismatch problems</action>
+           <action dev="POI-DEVELOPERS" type="add">45003 - Support embeded HDGF visio documents</action>
+           <action dev="POI-DEVELOPERS" type="fix">45001 - Partial fix for HWPF Range.insertBefore() and Range.delete() with unicode characters</action>
+           <action dev="POI-DEVELOPERS" type="fix">44977 - Support for AM/PM in excel date formats</action>
            <action dev="POI-DEVELOPERS" type="add">Support for specifying a policy to HSSF on missing / blank cells when fetching</action>
            <action dev="POI-DEVELOPERS" type="add">44937 - Partial support for extracting Escher images from HWPF files</action>
            <action dev="POI-DEVELOPERS" type="fix">44824 - Avoid an infinite loop when reading some HWPF pictures</action>

Modified: poi/branches/ooxml/src/java/org/apache/poi/POIDocument.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/POIDocument.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/POIDocument.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/POIDocument.java Fri May 23 02:48:23 2008
@@ -20,6 +20,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.Iterator;
 import java.util.List;
 
@@ -191,6 +192,11 @@
 			System.err.println("Couldn't write property set with name " + name + " as not supported by HPSF yet");
 		}
 	}
+	
+	/**
+	 * Writes the document out to the specified output stream
+	 */
+	public abstract void write(OutputStream out) throws IOException;
 
 	/**
 	 * Copies nodes from one POIFS to the other minus the excepts

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/model/FormulaParser.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/model/FormulaParser.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/model/FormulaParser.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/model/FormulaParser.java Fri May 23 02:48:23 2008
@@ -55,7 +55,7 @@
      */
     static final class FormulaParseException extends RuntimeException {
         // This class was given package scope until it would become clear that it is useful to
-        // general client code. 
+        // general client code.
         public FormulaParseException(String msg) {
             super(msg);
         }
@@ -127,42 +127,34 @@
             // Just return if so and reset 'look' to something to keep
             // SkipWhitespace from spinning
             look = (char)0;
-        }    
+        }
         pointer++;
         //System.out.println("Got char: "+ look);
     }
 
     /** Report What Was Expected */
     private RuntimeException expected(String s) {
-        String msg = "Parse error near char " + (pointer-1) + "'" + look + "'" 
+        String msg = "Parse error near char " + (pointer-1) + " '" + look + "'"
             + " in specified formula '" + formulaString + "'. Expected "
             + s;
         return new FormulaParseException(msg);
     }
 
-
-
     /** Recognize an Alpha Character */
     private boolean IsAlpha(char c) {
         return Character.isLetter(c) || c == '$' || c=='_';
     }
 
-
-
     /** Recognize a Decimal Digit */
     private boolean IsDigit(char c) {
-        //System.out.println("Checking digit for"+c);
         return Character.isDigit(c);
     }
 
-
-
     /** Recognize an Alphanumeric */
     private boolean  IsAlNum(char c) {
         return  (IsAlpha(c) || IsDigit(c));
     }
 
-
     /** Recognize White Space */
     private boolean IsWhite( char c) {
         return  (c ==' ' || c== TAB);
@@ -178,7 +170,7 @@
     /**
      *  Consumes the next input character if it is equal to the one specified otherwise throws an
      *  unchecked exception. This method does <b>not</b> consume whitespace (before or after the
-     *  matched character). 
+     *  matched character).
      */
     private void Match(char x) {
         if (look != x) {
@@ -218,7 +210,6 @@
         return Token.toString();
     }
 
-
     /** Get a Number */
     private String GetNum() {
         StringBuffer value = new StringBuffer();
@@ -281,18 +272,18 @@
         // This can be either a cell ref or a named range
         // Try to spot which it is
         boolean cellRef = CELL_REFERENCE_PATTERN.matcher(name).matches();
- 
+
         if (cellRef) {
             return new ReferencePtg(name);
         }
 
         for(int i = 0; i < book.getNumberOfNames(); i++) {
             // named range name matching is case insensitive
-        	if(book.getNameAt(i).getNameName().equalsIgnoreCase(name)) {
+            if(book.getNameAt(i).getNameName().equalsIgnoreCase(name)) {
                 return new NamePtg(name, book);
             }
         }
-        throw new FormulaParseException("Found reference to named range \"" 
+        throw new FormulaParseException("Found reference to named range \""
                     + name + "\", but that named range wasn't defined!");
     }
 
@@ -307,19 +298,19 @@
     /**
      * Note - Excel function names are 'case aware but not case sensitive'.  This method may end
      * up creating a defined name record in the workbook if the specified name is not an internal
-     * Excel function, and has not been encountered before. 
-     * 
-     * @param name case preserved function name (as it was entered/appeared in the formula). 
+     * Excel function, and has not been encountered before.
+     *
+     * @param name case preserved function name (as it was entered/appeared in the formula).
      */
     private Ptg function(String name) {
         int numArgs =0 ;
-        // Note regarding parameter - 
+        // Note regarding parameter -
         if(!AbstractFunctionPtg.isInternalFunctionName(name)) {
             // external functions get a Name token which points to a defined name record
             NamePtg nameToken = new NamePtg(name, this.book);
-            
+
             // in the token tree, the name is more or less the first argument
-            numArgs++;  
+            numArgs++;
             tokens.add(nameToken);
         }
         //average 2 args per function
@@ -477,26 +468,25 @@
     private static boolean isArgumentDelimiter(char ch) {
         return ch ==  ',' || ch == ')';
     }
-    
+
     /** get arguments to a function */
     private int Arguments(List argumentPointers) {
         SkipWhite();
         if(look == ')') {
             return 0;
         }
-        
+
         boolean missedPrevArg = true;
-        
         int numArgs = 0;
-        while(true) {
+        while (true) {
             SkipWhite();
-            if(isArgumentDelimiter(look)) {
-                if(missedPrevArg) {
+            if (isArgumentDelimiter(look)) {
+                if (missedPrevArg) {
                     tokens.add(new MissingArgPtg());
                     addArgumentPointer(argumentPointers);
                     numArgs++;
                 }
-                if(look == ')') {
+                if (look == ')') {
                     break;
                 }
                 Match(',');
@@ -507,6 +497,10 @@
             addArgumentPointer(argumentPointers);
             numArgs++;
             missedPrevArg = false;
+            SkipWhite();
+            if (!isArgumentDelimiter(look)) {
+                throw expected("',' or ')'");
+            }
         }
         return numArgs;
     }
@@ -524,7 +518,7 @@
             tokens.add(new PowerPtg());
         }
     }
-    
+
     private void percentFactor() {
         tokens.add(parseSimpleFactor());
         while(true) {
@@ -536,8 +530,8 @@
             tokens.add(new PercentPtg());
         }
     }
-    
-    
+
+
     /**
      * factors (without ^ or % )
      */
@@ -561,9 +555,6 @@
                 return new ParenthesisPtg();
             case '"':
                 return parseStringLiteral();
-            case ',':
-            case ')':
-                return new MissingArgPtg(); // TODO - not quite the right place to recognise a missing arg
         }
         if (IsAlpha(look) || look == '\''){
             return parseIdent();
@@ -707,10 +698,9 @@
     }
 
 
-    private StringPtg parseStringLiteral()
-    {
+    private StringPtg parseStringLiteral() {
         Match('"');
-        
+
         StringBuffer token = new StringBuffer();
         while (true) {
             if (look == '"') {
@@ -745,7 +735,7 @@
             return; // finished with Term
         }
     }
-    
+
     private void comparisonExpression() {
         concatExpression();
         while (true) {
@@ -787,7 +777,7 @@
         }
         return new LessThanPtg();
     }
-    
+
 
     private void concatExpression() {
         additiveExpression();
@@ -801,7 +791,7 @@
             tokens.add(new ConcatPtg());
         }
     }
-    
+
 
     /** Parse and Translate an Expression */
     private void additiveExpression() {
@@ -838,8 +828,9 @@
      **/
 
 
-    /** API call to execute the parsing of the formula
-     *
+    /**
+     *  API call to execute the parsing of the formula
+     * @deprecated use Ptg[] FormulaParser.parse(String, HSSFWorkbook) directly
      */
     public void parse() {
         pointer=0;
@@ -847,8 +838,8 @@
         comparisonExpression();
 
         if(pointer <= formulaLength) {
-            String msg = "Unused input [" + formulaString.substring(pointer-1) 
-                + "] after attempting to parse the formula [" + formulaString + "]"; 
+            String msg = "Unused input [" + formulaString.substring(pointer-1)
+                + "] after attempting to parse the formula [" + formulaString + "]";
             throw new FormulaParseException(msg);
         }
     }
@@ -863,11 +854,12 @@
      * a result of the parsing
      */
     public Ptg[] getRPNPtg() {
-     return getRPNPtg(FORMULA_TYPE_CELL);
+        return getRPNPtg(FORMULA_TYPE_CELL);
     }
 
     public Ptg[] getRPNPtg(int formulaType) {
         Node node = createTree();
+        // RVA is for 'operand class': 'reference', 'value', 'array'
         setRootLevelRVA(node, formulaType);
         setParameterRVA(node,formulaType);
         return (Ptg[]) tokens.toArray(new Ptg[0]);
@@ -948,7 +940,7 @@
         }
      }
     /**
-     * Convience method which takes in a list then passes it to the
+     * Convenience method which takes in a list then passes it to the
      *  other toFormulaString signature.
      * @param book   workbook for 3D and named references
      * @param lptgs  list of Ptg, can be null or empty
@@ -963,7 +955,7 @@
         return retval;
     }
     /**
-     * Convience method which takes in a list then passes it to the
+     * Convenience method which takes in a list then passes it to the
      *  other toFormulaString signature. Works on the current
      *  workbook for 3D and named references
      * @param lptgs  list of Ptg, can be null or empty
@@ -1011,7 +1003,7 @@
                     continue;
                     // but if it ever did, care must be taken:
                     // tAttrSpace comes *before* the operand it applies to, which may be consistent
-                    // with how the formula text appears but is against the RPN ordering assumed here 
+                    // with how the formula text appears but is against the RPN ordering assumed here
                 }
                 if (attrPtg.isSemiVolatile()) {
                     // similar to tAttrSpace - RPN is violated
@@ -1038,7 +1030,7 @@
             stack.push(o.toFormulaString(operands));
         }
         if(stack.isEmpty()) {
-            // inspection of the code above reveals that every stack.pop() is followed by a 
+            // inspection of the code above reveals that every stack.pop() is followed by a
             // stack.push(). So this is either an internal error or impossible.
             throw new IllegalStateException("Stack underflow");
         }

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/model/LinkTable.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/model/LinkTable.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/model/LinkTable.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/model/LinkTable.java Fri May 23 02:48:23 2008
@@ -41,7 +41,7 @@
  *
  *  In BIFF8 the Link Table consists of
  *  <ul>
- *  <li>one or more EXTERNALBOOK Blocks<p/>
+ *  <li>zero or more EXTERNALBOOK Blocks<p/>
  *  	each consisting of
  *  	<ul>
  *  	<li>exactly one EXTERNALBOOK (0x01AE) record</li>
@@ -55,7 +55,7 @@
  *  	</li>
  *  	</ul>
  *  </li>
- *  <li>exactly one EXTERNSHEET (0x0017) record</li>
+ *  <li>zero or one EXTERNSHEET (0x0017) record</li>
  *  <li>zero or more DEFINEDNAME (0x0018) records</li>
  *  </ul>
  *
@@ -63,6 +63,7 @@
  * @author Josh Micich
  */
 final class LinkTable {
+	// TODO make this class into a record aggregate
 
 	private static final class CRNBlock {
 
@@ -79,8 +80,8 @@
 			_crns = crns;
 		}
 		public CRNRecord[] getCrns() {
-            return (CRNRecord[]) _crns.clone();
-        }
+			return (CRNRecord[]) _crns.clone();
+		}
 	}
 
 	private static final class ExternalBookBlock {
@@ -136,16 +137,19 @@
 		while(rs.peekNextClass() == SupBookRecord.class) {
 		   temp.add(new ExternalBookBlock(rs));
 		}
-		if(temp.size() < 1) {
-			throw new RuntimeException("Need at least one EXTERNALBOOK blocks");
-		}
+		
 		_externalBookBlocks = new ExternalBookBlock[temp.size()];
 		temp.toArray(_externalBookBlocks);
 		temp.clear();
-
-		// If link table is present, there is always 1 of ExternSheetRecord
-		Record next = rs.getNext();
-		_externSheetRecord = (ExternSheetRecord)next;
+		
+		if (_externalBookBlocks.length > 0) {
+			// If any ExternalBookBlock present, there is always 1 of ExternSheetRecord
+			Record next = rs.getNext();
+			_externSheetRecord = (ExternSheetRecord) next;
+		} else {
+			_externSheetRecord = null;
+		}
+		
 		_definedNames = new ArrayList();
 		// collect zero or more DEFINEDNAMEs id=0x18
 		while(rs.peekNextClass() == NameRecord.class) {
@@ -222,7 +226,7 @@
 	public void addName(NameRecord name) {
 		_definedNames.add(name);
 
-	   // TODO - this is messy
+		// TODO - this is messy
 		// Not the most efficient way but the other way was causing too many bugs
 		int idx = findFirstRecordLocBySid(ExternSheetRecord.sid);
 		if (idx == -1) idx = findFirstRecordLocBySid(SupBookRecord.sid);
@@ -242,8 +246,8 @@
 
 	public int getSheetIndexFromExternSheetIndex(int externSheetNumber) {
 		if (externSheetNumber >= _externSheetRecord.getNumOfREFStructures()) {
-            return -1;
-        }
+			return -1;
+		}
 		return _externSheetRecord.getREFRecordAt(externSheetNumber).getIndexToFirstSupBook();
 	}
 
@@ -265,7 +269,7 @@
 			ExternSheetSubRecord esr = _externSheetRecord.getREFRecordAt(i);
 
 			if (esr.getIndexToFirstSupBook() ==  sheetNumber
-			        && esr.getIndexToLastSupBook() == sheetNumber){
+					&& esr.getIndexToLastSupBook() == sheetNumber){
 				return i;
 			}
 		}

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Sheet.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Sheet.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Sheet.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Sheet.java Fri May 23 02:48:23 2008
@@ -96,8 +96,8 @@
     protected List                       condFormatting    =     new ArrayList();
 
     /** Add an UncalcedRecord if not true indicating formulas have not been calculated */
-    protected boolean uncalced = false;
-	
+    protected boolean _isUncalced = false;
+    
     public static final byte PANE_LOWER_RIGHT = (byte)0;
     public static final byte PANE_UPPER_RIGHT = (byte)1;
     public static final byte PANE_LOWER_LEFT = (byte)2;
@@ -162,7 +162,7 @@
                 }
             }
             else if (rec.getSid() == UncalcedRecord.sid) {
-                retval.uncalced = true;
+                retval._isUncalced = true;
             }
             else if (rec.getSid() == DimensionsRecord.sid)
             {
@@ -329,16 +329,8 @@
             }
         }
         retval.records = records;
-//        if (retval.rows == null)
-//        {
-//            retval.rows = new RowRecordsAggregate();
-//        }
         retval.checkCells();
         retval.checkRows();
-//        if (retval.cells == null)
-//        {
-//            retval.cells = new ValueRecordsAggregate();
-//        }
         if (log.check( POILogger.DEBUG ))
             log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");
         return retval;
@@ -816,17 +808,17 @@
             // Once the rows have been found in the list of records, start
             //  writing out the blocked row information. This includes the DBCell references
             if (record instanceof RowRecordsAggregate) {
-              pos += ((RowRecordsAggregate)record).serialize(pos, data, cells);   // rec.length;
+              pos += ((RowRecordsAggregate)record).serialize(pos, data, cells);
             } else if (record instanceof ValueRecordsAggregate) {
               //Do nothing here. The records were serialized during the RowRecordAggregate block serialization
             } else {
-              pos += record.serialize(pos, data );   // rec.length;
+              pos += record.serialize(pos, data );
             }
 
             // If the BOF record was just serialized then add the IndexRecord
             if (record.getSid() == BOFRecord.sid) {
               // Add an optional UncalcedRecord
-              if (uncalced) {
+              if (_isUncalced) {
                   UncalcedRecord rec = new UncalcedRecord();
                   pos += rec.serialize(pos, data);
               }
@@ -837,31 +829,10 @@
                 pos += serializeIndexRecord(k, pos, data);
               }
             }
-
-            //// uncomment to test record sizes ////
-//            System.out.println( record.getClass().getName() );
-//            byte[] data2 = new byte[record.getRecordSize()];
-//            record.serialize(0, data2 );   // rec.length;
-//            if (LittleEndian.getUShort(data2, 2) != record.getRecordSize() - 4
-//                    && record instanceof RowRecordsAggregate == false
-//                    && record instanceof ValueRecordsAggregate == false
-//                    && record instanceof EscherAggregate == false)
-//            {
-//                throw new RuntimeException("Blah!!!  Size off by " + ( LittleEndian.getUShort(data2, 2) - record.getRecordSize() - 4) + " records.");
-//            }
-
-//asd:            int len = record.serialize(pos + offset, data );
-
-            /////  DEBUG BEGIN /////
-//asd:            if (len != record.getRecordSize())
-//asd:                throw new IllegalStateException("Record size does not match serialized bytes.  Serialized size = " + len + " but getRecordSize() returns " + record.getRecordSize() + ". Record object is " + record.getClass());
-            /////  DEBUG END /////
-
-//asd:            pos += len;   // rec.length;
-
         }
-        if (log.check( POILogger.DEBUG ))
+        if (log.check( POILogger.DEBUG )) {
             log.log(POILogger.DEBUG, "Sheet.serialize returning ");
+        }
         return pos-offset;
     }
 
@@ -875,10 +846,17 @@
       for (int j = BOFRecordIndex+1; j < records.size(); j++)
       {
         Record tmpRec = (( Record ) records.get(j));
-        if (tmpRec instanceof RowRecordsAggregate)
-          break;
+        if (tmpRec instanceof UncalcedRecord) {
+            continue;
+        }
+        if (tmpRec instanceof RowRecordsAggregate) {
+            break;
+        }
         sheetRecSize+= tmpRec.getRecordSize();
       }
+      if (_isUncalced) {
+          sheetRecSize += UncalcedRecord.getStaticRecordSize();
+      }
       //Add the references to the DBCells in the IndexRecord (one for each block)
       int blockCount = rows.getRowBlockCount();
       //Calculate the size of this IndexRecord
@@ -2017,31 +1995,33 @@
     {
         int retval = 0;
 
-        for ( int k = 0; k < records.size(); k++ )
-        {
-            retval += ( (Record) records.get( k ) ).getRecordSize();
+        for ( int k = 0; k < records.size(); k++) {
+            Record record = (Record) records.get(k);
+            if (record instanceof UncalcedRecord) {
+                // skip the UncalcedRecord if present, it's only encoded if the isUncalced flag is set
+                continue;
+            }
+            retval += record.getRecordSize();
         }
-        //Add space for the IndexRecord
         if (rows != null) {
-            final int blocks = rows.getRowBlockCount();
-            retval += IndexRecord.getRecordSizeForBlockCount(blocks);
-
-            //Add space for the DBCell records
-            //Once DBCell per block.
-            //8 bytes per DBCell (non variable section)
-            //2 bytes per row reference
-            retval += (8 * blocks);
-            for (Iterator itr = rows.getIterator(); itr.hasNext();) {
-                RowRecord row = (RowRecord)itr.next();
-                if (cells != null && cells.rowHasCells(row.getRowNumber()))
-                    retval += 2;
+            // Add space for the IndexRecord and DBCell records
+            final int nBlocks = rows.getRowBlockCount();
+            int nRows = 0;
+            if (cells != null) {
+                for (Iterator itr = rows.getIterator(); itr.hasNext();) {
+                    RowRecord row = (RowRecord)itr.next();
+                    if (cells.rowHasCells(row.getRowNumber())) {
+                        nRows++;
+                    }
+                }
             }
+            retval += IndexRecord.getRecordSizeForBlockCount(nBlocks);
+            retval += DBCellRecord.calculateSizeOfRecords(nBlocks, nRows);
         }
         // Add space for UncalcedRecord
-        if (uncalced) {
+        if (_isUncalced) {
             retval += UncalcedRecord.getStaticRecordSize();
         }
-
         return retval;
     }
 
@@ -2518,13 +2498,13 @@
      * @return whether an uncalced record must be inserted or not at generation
      */
     public boolean getUncalced() {
-        return uncalced;
+        return _isUncalced;
     }
     /**
      * @param uncalced whether an uncalced record must be inserted or not at generation
      */
     public void setUncalced(boolean uncalced) {
-        this.uncalced = uncalced;
+        this._isUncalced = uncalced;
     }
 
     /**

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/model/Workbook.java Fri May 23 02:48:23 2008
@@ -191,12 +191,11 @@
                 case ExternSheetRecord.sid :
                     throw new RuntimeException("Extern sheet is part of LinkTable");
                 case NameRecord.sid :
-                    throw new RuntimeException("DEFINEDNAME is part of LinkTable");
                 case SupBookRecord.sid :
+                    // LinkTable can start with either of these
                     if (log.check( POILogger.DEBUG ))
                         log.log(DEBUG, "found SupBook record at " + k);
                     retval.linkTable = new LinkTable(recs, k, retval.records);
-                    //                    retval.records.supbookpos = k;
                     k+=retval.linkTable.getRecordCount() - 1;
                     continue;
                 case FormatRecord.sid :

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/DBCellRecord.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/DBCellRecord.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/DBCellRecord.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/DBCellRecord.java Fri May 23 02:48:23 2008
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,7 +14,6 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
@@ -29,10 +27,7 @@
  * @author Jason Height
  * @version 2.0-pre
  */
-
-public class DBCellRecord
-    extends Record
-{
+public final class DBCellRecord extends Record {
     public final static int BLOCK_SIZE = 32;
     public final static short sid = 0xd7;
     private int               field_1_row_offset;
@@ -46,7 +41,6 @@
      * Constructs a DBCellRecord and sets its fields appropriately
      * @param in the RecordInputstream to read the record from
      */
-
     public DBCellRecord(RecordInputStream in)
     {
         super(in);
@@ -78,7 +72,6 @@
      *
      * @param offset    offset to the start of the first cell in the next DBCell block
      */
-
     public void setRowOffset(int offset)
     {
         field_1_row_offset = offset;
@@ -108,7 +101,6 @@
      *
      * @return rowoffset to the start of the first cell in the next DBCell block
      */
-
     public int getRowOffset()
     {
         return field_1_row_offset;
@@ -120,7 +112,6 @@
      * @param index of the cell offset to retrieve
      * @return celloffset from the celloffset array
      */
-
     public short getCellOffsetAt(int index)
     {
         return field_2_cell_offsets[ index ];
@@ -131,7 +122,6 @@
      *
      * @return number of cell offsets
      */
-
     public int getNumCellOffsets()
     {
         return field_2_cell_offsets.length;
@@ -175,9 +165,15 @@
         return 8 + (getNumCellOffsets() * 2);
     }
     
-    /** Returns the size of a DBCellRecord when it needs to reference a certain number of rows*/
-    public static int getRecordSizeForRows(int rows) {
-      return 8 + (rows * 2);
+    /**
+     *  @returns the size of the group of <tt>DBCellRecord</tt>s needed to encode
+     *  the specified number of blocks and rows
+     */
+    public static int calculateSizeOfRecords(int nBlocks, int nRows) {
+        // One DBCell per block.
+        // 8 bytes per DBCell (non variable section)
+        // 2 bytes per row reference
+        return nBlocks * 8 + nRows * 2;
     }
 
     public short getSid()

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java Fri May 23 02:48:23 2008
@@ -27,7 +27,7 @@
 
 
 /**
- * Title:        Area 3D Ptg - 3D referecnce (Sheet + Area)<P>
+ * Title:        Area 3D Ptg - 3D reference (Sheet + Area)<P>
  * Description:  Defined a area in Extern Sheet. <P>
  * REFERENCE:  <P>
  * @author Libin Roman (Vista Portal LDT. Developer)
@@ -35,7 +35,6 @@
  * @author Jason Height (jheight at chariot dot net dot au)
  * @version 1.0-pre
  */
-
 public class Area3DPtg extends Ptg implements AreaI
 {
 	public final static byte sid = 0x3b;
@@ -84,23 +83,15 @@
 		  setExternSheetIndex(externalSheetIndex);
 	}
 
-	public String toString()
-	{
-		StringBuffer buffer = new StringBuffer();
-
-		buffer.append( "AreaPtg\n" );
-		buffer.append( "Index to Extern Sheet = " + getExternSheetIndex() ).append( "\n" );
-		buffer.append( "firstRow = " + getFirstRow() ).append( "\n" );
-		buffer.append( "lastRow  = " + getLastRow() ).append( "\n" );
-		buffer.append( "firstCol = " + getFirstColumn() ).append( "\n" );
-		buffer.append( "lastCol  = " + getLastColumn() ).append( "\n" );
-		buffer.append( "firstColRel= "
-				+ isFirstRowRelative() ).append( "\n" );
-		buffer.append( "lastColRowRel = "
-				+ isLastRowRelative() ).append( "\n" );
-		buffer.append( "firstColRel   = " + isFirstColRelative() ).append( "\n" );
-		buffer.append( "lastColRel	= " + isLastColRelative() ).append( "\n" );
-		return buffer.toString();
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append(getClass().getName());
+		sb.append(" [");
+		sb.append("sheetIx=").append(getExternSheetIndex());
+		sb.append(" ! ");
+		sb.append(AreaReference.formatAsString(this));
+		sb.append("]");
+		return sb.toString();
 	}
 
 	public void writeBytes( byte[] array, int offset )
@@ -284,7 +275,7 @@
 		}
 		
 		// Now the normal area bit
-		retval.append( AreaPtg.toFormulaString(this, book) );
+		retval.append(AreaReference.formatAsString(this));
 		
 		// All done
 		return retval.toString();
@@ -326,6 +317,7 @@
 
 	public int hashCode()
 	{
+		// TODO - hashCode seems to be unused
 		int result;
 		result = (int) field_1_index_extern_sheet;
 		result = 29 * result + (int) field_2_first_row;

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/record/formula/AreaPtg.java Fri May 23 02:48:23 2008
@@ -114,23 +114,13 @@
       return "AreaPtg";
     }    
 
-    public String toString()
-    {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append(getAreaPtgName());
-        buffer.append("\n");
-        buffer.append("firstRow = " + getFirstRow()).append("\n");
-        buffer.append("lastRow  = " + getLastRow()).append("\n");
-        buffer.append("firstCol = " + getFirstColumn()).append("\n");
-        buffer.append("lastCol  = " + getLastColumn()).append("\n");
-        buffer.append("firstColRowRel= "
-                      + isFirstRowRelative()).append("\n");
-        buffer.append("lastColRowRel = "
-                      + isLastRowRelative()).append("\n");
-        buffer.append("firstColRel   = " + isFirstColRelative()).append("\n");
-        buffer.append("lastColRel    = " + isLastColRelative()).append("\n");
-        return buffer.toString();
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append(" [");
+        sb.append(AreaReference.formatAsString(this));
+        sb.append("]");
+        return sb.toString();
     }
 
     public void writeBytes(byte [] array, int offset) {
@@ -307,19 +297,8 @@
         field_4_last_column = column;
     }
     
-    public String toFormulaString(Workbook book)
-    {
-    	return toFormulaString(this, book);
-    }
-    protected static String toFormulaString(AreaI area, Workbook book) {
-    	CellReference topLeft = new CellReference(area.getFirstRow(),area.getFirstColumn(),!area.isFirstRowRelative(),!area.isFirstColRelative());
-    	CellReference botRight = new CellReference(area.getLastRow(),area.getLastColumn(),!area.isLastRowRelative(),!area.isLastColRelative());
-    	
-    	if(AreaReference.isWholeColumnReference(topLeft, botRight)) {
-    		return (new AreaReference(topLeft, botRight)).formatAsString();
-    	} else {
-    		return topLeft.formatAsString() + ":" + botRight.formatAsString(); 
-    	}
+    public String toFormulaString(Workbook book) {
+        return AreaReference.formatAsString(this);
     }
 
     public byte getDefaultOperandClass() {

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Fri May 23 02:48:23 2008
@@ -15,12 +15,6 @@
    limitations under the License.
 ==================================================================== */
 
-
-/*
- * HSSFWorkbook.java
- *
- * Created on September 30, 2001, 3:37 PM
- */
 package org.apache.poi.hssf.usermodel;
 
 import java.io.ByteArrayInputStream;
@@ -81,7 +75,6 @@
  * @author  Shawn Laubach (slaubach at apache dot org)
  * @version 2.0-pre
  */
-
 public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.usermodel.Workbook
 {
     private static final int DEBUG = POILogger.DEBUG;
@@ -105,7 +98,7 @@
      * this holds the HSSFSheet objects attached to this workbook
      */
 
-    protected ArrayList sheets;
+    protected List _sheets;
 
     /**
      * this holds the HSSFName objects attached to this workbook
@@ -159,7 +152,7 @@
     {
         super(null, null);
         workbook = book;
-        sheets = new ArrayList( INITIAL_CAPACITY );
+        _sheets = new ArrayList( INITIAL_CAPACITY );
         names = new ArrayList( INITIAL_CAPACITY );
     }
 
@@ -250,7 +243,7 @@
            this.directory = null;
         }
 
-        sheets = new ArrayList(INITIAL_CAPACITY);
+        _sheets = new ArrayList(INITIAL_CAPACITY);
         names  = new ArrayList(INITIAL_CAPACITY);
 
         // Grab the data from the workbook stream, however
@@ -280,7 +273,7 @@
 
             HSSFSheet hsheet = new HSSFSheet(this, sheet);
 
-            sheets.add(hsheet);
+            _sheets.add(hsheet);
 
             // workbook.setSheetName(sheets.size() -1, "Sheet"+sheets.size());
         }
@@ -378,12 +371,12 @@
      */
 
     public void setSheetOrder(String sheetname, int pos ) {
-        sheets.add(pos,sheets.remove(getSheetIndex(sheetname)));
+        _sheets.add(pos,_sheets.remove(getSheetIndex(sheetname)));
         workbook.setSheetOrder(sheetname, pos);
     }
 
     private void validateSheetIndex(int index) {
-        int lastSheetIx = sheets.size() - 1;
+        int lastSheetIx = _sheets.size() - 1;
         if (index < 0 || index > lastSheetIx) {
             throw new IllegalArgumentException("Sheet index (" 
                     + index +") is out of range (0.." +    lastSheetIx + ")");
@@ -397,7 +390,7 @@
     public void setSelectedTab(int index) {
         
         validateSheetIndex(index);
-        int nSheets = sheets.size();
+        int nSheets = _sheets.size();
         for (int i=0; i<nSheets; i++) {
                getSheetAt(i).setSelected(i == index);
         }
@@ -415,7 +408,7 @@
         for (int i = 0; i < indexes.length; i++) {
             validateSheetIndex(indexes[i]);
         }
-        int nSheets = sheets.size();
+        int nSheets = _sheets.size();
         for (int i=0; i<nSheets; i++) {
             boolean bSelect = false;
             for (int j = 0; j < indexes.length; j++) {
@@ -437,7 +430,7 @@
     public void setActiveSheet(int index) {
         
         validateSheetIndex(index);
-        int nSheets = sheets.size();
+        int nSheets = _sheets.size();
         for (int i=0; i<nSheets; i++) {
              getSheetAt(i).setActive(i == index);
         }
@@ -509,19 +502,15 @@
      * set the sheet name.
      * Will throw IllegalArgumentException if the name is greater than 31 chars
      * or contains /\?*[]
-     * @param sheet number (0 based)
+     * @param sheetIx number (0 based)
      */
-    public void setSheetName(int sheet, String name)
+    public void setSheetName(int sheetIx, String name)
     {
-        if (workbook.doesContainsSheetName( name, sheet ))
+        if (workbook.doesContainsSheetName( name, sheetIx )) {
             throw new IllegalArgumentException( "The workbook already contains a sheet with this name" );
-
-        if (sheet > (sheets.size() - 1))
-        {
-            throw new RuntimeException("Sheet out of bounds");
         }
-
-        workbook.setSheetName( sheet, name);
+        validateSheetIndex(sheetIx);
+        workbook.setSheetName(sheetIx, name);
     }
 
 
@@ -533,15 +522,12 @@
      * or contains /\?*[]
      * @param sheet number (0 based)
      */
-    public void setSheetName( int sheet, String name, short encoding )
+    public void setSheetName(int sheetIx, String name, short encoding)
     {
-        if (workbook.doesContainsSheetName( name, sheet ))
+        if (workbook.doesContainsSheetName( name, sheetIx )) {
             throw new IllegalArgumentException( "The workbook already contains a sheet with this name" );
-
-        if (sheet > (sheets.size() - 1))
-        {
-            throw new RuntimeException("Sheet out of bounds");
         }
+        validateSheetIndex(sheetIx);
 
         switch ( encoding ) {
         case ENCODING_COMPRESSED_UNICODE:
@@ -553,51 +539,39 @@
             throw new RuntimeException( "Unsupported encoding" );
         }
 
-        workbook.setSheetName( sheet, name, encoding );
+        workbook.setSheetName( sheetIx, name, encoding );
     }
 
     /**
      * get the sheet name
-     * @param sheet Number
+     * @param sheetIx Number
      * @return Sheet name
      */
-
-    public String getSheetName(int sheet)
+    public String getSheetName(int sheetIx)
     {
-        if (sheet > (sheets.size() - 1))
-        {
-            throw new RuntimeException("Sheet out of bounds");
-        }
-        return workbook.getSheetName(sheet);
+        validateSheetIndex(sheetIx);
+        return workbook.getSheetName(sheetIx);
     }
 
     /**
      * check whether a sheet is hidden
-     * @param sheet Number
+     * @param sheetIx Number
      * @return True if sheet is hidden
      */
-
-    public boolean isSheetHidden(int sheet) {
-        if (sheet > (sheets.size() - 1))
-        {
-            throw new RuntimeException("Sheet out of bounds");
-        }
-        return workbook.isSheetHidden(sheet);
+    public boolean isSheetHidden(int sheetIx) {
+        validateSheetIndex(sheetIx);
+        return workbook.isSheetHidden(sheetIx);
     }
 
     /**
      * Hide or unhide a sheet
      *
-     * @param sheetnum The sheet number
+     * @param sheetIx The sheet index
      * @param hidden True to mark the sheet as hidden, false otherwise
      */
-
-    public void setSheetHidden(int sheet, boolean hidden) {
-        if (sheet > (sheets.size() - 1))
-        {
-            throw new RuntimeException("Sheet out of bounds");
-        }
-        workbook.setSheetHidden(sheet,hidden);
+    public void setSheetHidden(int sheetIx, boolean hidden) {
+        validateSheetIndex(sheetIx);
+        workbook.setSheetHidden(sheetIx, hidden);
     }
 
     /*
@@ -619,12 +593,12 @@
 
     /** Returns the index of the given sheet
      * @param sheet the sheet to look up
-     * @return index of the sheet (0 based)
+     * @return index of the sheet (0 based). <tt>-1</tt> if not found
      */
     public int getSheetIndex(org.apache.poi.ss.usermodel.Sheet sheet)
     {
-        for(int i=0; i<sheets.size(); i++) {
-            if(sheets.get(i) == sheet) {
+        for(int i=0; i<_sheets.size(); i++) {
+            if(_sheets.get(i) == sheet) {
                 return i;
             }
         }
@@ -653,9 +627,9 @@
     {
         HSSFSheet sheet = new HSSFSheet(this);
 
-        sheets.add(sheet);
-        workbook.setSheetName(sheets.size() - 1, "Sheet" + (sheets.size() - 1));
-        boolean isOnlySheet = sheets.size() == 1;
+        _sheets.add(sheet);
+        workbook.setSheetName(_sheets.size() - 1, "Sheet" + (_sheets.size() - 1));
+        boolean isOnlySheet = _sheets.size() == 1;
         sheet.setSelected(isOnlySheet);
         sheet.setActive(isOnlySheet);
         return sheet;
@@ -669,13 +643,13 @@
 
     public HSSFSheet cloneSheet(int sheetNum) {
         validateSheetIndex(sheetNum);
-        HSSFSheet srcSheet = (HSSFSheet) sheets.get(sheetNum);
+        HSSFSheet srcSheet = (HSSFSheet) _sheets.get(sheetNum);
         String srcName = workbook.getSheetName(sheetNum);
         HSSFSheet clonedSheet = srcSheet.cloneSheet(this);
         clonedSheet.setSelected(false);
         clonedSheet.setActive(false);
 
-        sheets.add(clonedSheet);
+        _sheets.add(clonedSheet);
         int i = 1;
         while (true) {
             // Try and find the next sheet name that is unique
@@ -689,7 +663,7 @@
 
             //If the sheet name is unique, then set it otherwise move on to the next number.
             if (workbook.getSheetIndex(name) == -1) {
-              workbook.setSheetName(sheets.size()-1, name);
+              workbook.setSheetName(_sheets.size()-1, name);
               break;
             }
         }
@@ -710,14 +684,14 @@
 
     public HSSFSheet createSheet(String sheetname)
     {
-        if (workbook.doesContainsSheetName( sheetname, sheets.size() ))
+        if (workbook.doesContainsSheetName( sheetname, _sheets.size() ))
             throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
 
         HSSFSheet sheet = new HSSFSheet(this);
 
-        sheets.add(sheet);
-        workbook.setSheetName(sheets.size() - 1, sheetname);
-        boolean isOnlySheet = sheets.size() == 1;
+        _sheets.add(sheet);
+        workbook.setSheetName(_sheets.size() - 1, sheetname);
+        boolean isOnlySheet = _sheets.size() == 1;
         sheet.setSelected(isOnlySheet);
         sheet.setActive(isOnlySheet);
         return sheet;
@@ -730,13 +704,19 @@
 
     public int getNumberOfSheets()
     {
-        return sheets.size();
+        return _sheets.size();
     }
 
     public int getSheetIndexFromExternSheetIndex(int externSheetNumber) {
     	return workbook.getSheetIndexFromExternSheetIndex(externSheetNumber);
 	}
 
+    private HSSFSheet[] getSheets() {
+        HSSFSheet[] result = new HSSFSheet[_sheets.size()];
+        _sheets.toArray(result);
+        return result;
+    }
+
 	/**
      * Get the HSSFSheet object at the given index.
      * @param index of the sheet number (0-based physical & logical)
@@ -745,7 +725,7 @@
 
     public HSSFSheet getSheetAt(int index)
     {
-        return (HSSFSheet) sheets.get(index);
+        return (HSSFSheet) _sheets.get(index);
     }
 
     /**
@@ -758,13 +738,13 @@
     {
         HSSFSheet retval = null;
 
-        for (int k = 0; k < sheets.size(); k++)
+        for (int k = 0; k < _sheets.size(); k++)
         {
             String sheetname = workbook.getSheetName(k);
 
             if (sheetname.equalsIgnoreCase(name))
             {
-                retval = (HSSFSheet) sheets.get(k);
+                retval = (HSSFSheet) _sheets.get(k);
             }
         }
         return retval;
@@ -793,11 +773,11 @@
         boolean wasActive = getSheetAt(index).isActive();
         boolean wasSelected = getSheetAt(index).isSelected();
 
-        sheets.remove(index);
+        _sheets.remove(index);
         workbook.removeSheet(index);
 
         // set the remaining active/selected sheet
-        int nSheets = sheets.size();
+        int nSheets = _sheets.size();
         if (nSheets < 1) {
             // nothing more to do if there are no sheets left
             return;
@@ -1173,48 +1153,47 @@
 
     public byte[] getBytes()
     {
-        if (log.check( POILogger.DEBUG ))
+        if (log.check( POILogger.DEBUG )) {
             log.log(DEBUG, "HSSFWorkbook.getBytes()");
+        }
+        
+        HSSFSheet[] sheets = getSheets();
+        int nSheets = sheets.length;
 
         // before getting the workbook size we must tell the sheets that
         // serialization is about to occur.
-        for (int k = 0; k < sheets.size(); k++)
-            ((HSSFSheet) sheets.get(k)).getSheet().preSerialize();
-
-        int wbsize = workbook.getSize();
+        for (int i = 0; i < nSheets; i++) {
+            sheets[i].getSheet().preSerialize();
+        }
 
-        // log.debug("REMOVEME: old sizing method "+workbook.serialize().length);
-        // ArrayList sheetbytes = new ArrayList(sheets.size());
-        int totalsize = wbsize;
+        int totalsize = workbook.getSize();
 
-        for (int k = 0; k < sheets.size(); k++)
-        {
+        // pre-calculate all the sheet sizes and set BOF indexes
+        int[] estimatedSheetSizes = new int[nSheets];
+        for (int k = 0; k < nSheets; k++) {
             workbook.setSheetBof(k, totalsize);
-            totalsize += ((HSSFSheet) sheets.get(k)).getSheet().getSize();
+            int sheetSize = sheets[k].getSheet().getSize();
+            estimatedSheetSizes[k] = sheetSize;
+            totalsize += sheetSize;
         }
 
 
-/*        if (totalsize < 4096)
-        {
-            totalsize = 4096;
-        }*/
         byte[] retval = new byte[totalsize];
         int pos = workbook.serialize(0, retval);
 
-        // System.arraycopy(wb, 0, retval, 0, wb.length);
-        for (int k = 0; k < sheets.size(); k++)
-        {
-
-            // byte[] sb = (byte[])sheetbytes.get(k);
-            // System.arraycopy(sb, 0, retval, pos, sb.length);
-            int len = ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos,
-                                retval);
-            pos += len;   // sb.length;
+        for (int k = 0; k < nSheets; k++) {
+            int serializedSize = sheets[k].getSheet().serialize(pos, retval);
+            if (serializedSize != estimatedSheetSizes[k]) {
+                // Wrong offset values have been passed in the call to setSheetBof() above.
+                // For books with more than one sheet, this discrepancy would cause excel 
+                // to report errors and loose data while reading the workbook
+                throw new IllegalStateException("Actual serialized sheet size (" + serializedSize 
+                        + ") differs from pre-calculated size (" + estimatedSheetSizes[k] 
+                        + ") for sheet (" + k + ")");
+                // TODO - add similar sanity check to ensure that Sheet.serializeIndexRecord() does not write mis-aligned offsets either
+            }
+            pos += serializedSize;
         }
-/*        for (int k = pos; k < totalsize; k++)
-        {
-            retval[k] = 0;
-        }*/
         return retval;
     }
 

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/util/AreaReference.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/util/AreaReference.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/util/AreaReference.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/util/AreaReference.java Fri May 23 02:48:23 2008
@@ -15,12 +15,13 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.util;
 
 import java.util.ArrayList;
 import java.util.StringTokenizer;
 
+import org.apache.poi.hssf.record.formula.AreaI;
+
 public final class AreaReference {
 
     /** The character (!) that separates sheet names from cell references */ 
@@ -50,13 +51,13 @@
         
         // Special handling for whole-column references
         if(parts.length == 2 && parts[0].length() == 1 &&
-        		parts[1].length() == 1 && 
-        		parts[0].charAt(0) >= 'A' && parts[0].charAt(0) <= 'Z' &&
-        		parts[1].charAt(0) >= 'A' && parts[1].charAt(0) <= 'Z') {
-        	// Represented internally as x$1 to x$65536
-        	//  which is the maximum range of rows
-        	parts[0] = parts[0] + "$1";
-        	parts[1] = parts[1] + "$65536";
+                parts[1].length() == 1 && 
+                parts[0].charAt(0) >= 'A' && parts[0].charAt(0) <= 'Z' &&
+                parts[1].charAt(0) >= 'A' && parts[1].charAt(0) <= 'Z') {
+            // Represented internally as x$1 to x$65536
+            //  which is the maximum range of rows
+            parts[0] = parts[0] + "$1";
+            parts[1] = parts[1] + "$65536";
         }
         
         _firstCell = new CellReference(parts[0]);
@@ -74,9 +75,9 @@
      * Creates an area ref from a pair of Cell References.
      */
     public AreaReference(CellReference topLeft, CellReference botRight) {
-    	_firstCell = topLeft;
-    	_lastCell = botRight;
-    	_isSingleCell = false;
+        _firstCell = topLeft;
+        _lastCell = botRight;
+        _isSingleCell = false;
     }
 
     /**
@@ -98,17 +99,17 @@
      *  such as C:C or D:G ?
      */
     public static boolean isWholeColumnReference(CellReference topLeft, CellReference botRight) {
-    	// These are represented as something like
-    	//   C$1:C$65535 or D$1:F$0
-    	// i.e. absolute from 1st row to 0th one
-    	if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() &&
-    		botRight.getRow() == 65535 && botRight.isRowAbsolute()) {
-    		return true;
-    	}
-    	return false;
+        // These are represented as something like
+        //   C$1:C$65535 or D$1:F$0
+        // i.e. absolute from 1st row to 0th one
+        if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() &&
+            botRight.getRow() == 65535 && botRight.isRowAbsolute()) {
+            return true;
+        }
+        return false;
     }
     public boolean isWholeColumnReference() {
-    	return isWholeColumnReference(_firstCell, _lastCell);
+        return isWholeColumnReference(_firstCell, _lastCell);
     }
 
     /**
@@ -155,26 +156,26 @@
      * Returns a reference to every cell covered by this area
      */
     public CellReference[] getAllReferencedCells() {
-    	// Special case for single cell reference
-    	if(_isSingleCell) {
-    		return  new CellReference[] { _firstCell, };
-    	}
+        // Special case for single cell reference
+        if(_isSingleCell) {
+            return  new CellReference[] { _firstCell, };
+        }
  
-    	// Interpolate between the two
+        // Interpolate between the two
         int minRow = Math.min(_firstCell.getRow(), _lastCell.getRow());
-    	int maxRow = Math.max(_firstCell.getRow(), _lastCell.getRow());
-    	int minCol = Math.min(_firstCell.getCol(), _lastCell.getCol());
-    	int maxCol = Math.max(_firstCell.getCol(), _lastCell.getCol());
+        int maxRow = Math.max(_firstCell.getRow(), _lastCell.getRow());
+        int minCol = Math.min(_firstCell.getCol(), _lastCell.getCol());
+        int maxCol = Math.max(_firstCell.getCol(), _lastCell.getCol());
         String sheetName = _firstCell.getSheetName();
-    	
-    	ArrayList refs = new ArrayList();
-    	for(int row=minRow; row<=maxRow; row++) {
-    		for(int col=minCol; col<=maxCol; col++) {
-    			CellReference ref = new CellReference(sheetName, row, col, _firstCell.isRowAbsolute(), _firstCell.isColAbsolute());
-    			refs.add(ref);
-    		}
-    	}
-    	return (CellReference[])refs.toArray(new CellReference[refs.size()]);
+        
+        ArrayList refs = new ArrayList();
+        for(int row=minRow; row<=maxRow; row++) {
+            for(int col=minCol; col<=maxCol; col++) {
+                CellReference ref = new CellReference(sheetName, row, col, _firstCell.isRowAbsolute(), _firstCell.isColAbsolute());
+                refs.add(ref);
+            }
+        }
+        return (CellReference[])refs.toArray(new CellReference[refs.size()]);
     }
 
     /**
@@ -189,14 +190,14 @@
      * @return the text representation of this area reference as it would appear in a formula.
      */
     public String formatAsString() {
-    	// Special handling for whole-column references
-    	if(isWholeColumnReference()) {
-    		return
-    			CellReference.convertNumToColString(_firstCell.getCol())
-    			+ ":" +
-    			CellReference.convertNumToColString(_lastCell.getCol());
-    	}
-    	
+        // Special handling for whole-column references
+        if(isWholeColumnReference()) {
+            return
+                CellReference.convertNumToColString(_firstCell.getCol())
+                + ":" +
+                CellReference.convertNumToColString(_lastCell.getCol());
+        }
+        
         StringBuffer sb = new StringBuffer(32);
         sb.append(_firstCell.formatAsString());
         if(!_isSingleCell) {
@@ -210,6 +211,18 @@
         }
         return sb.toString();
     }
+    /**
+     * Formats a 2-D area as it would appear in a formula.  See formatAsString() (no-arg)
+     */
+    public static String formatAsString(AreaI area) {
+        CellReference topLeft = new CellReference(area.getFirstRow(),area.getFirstColumn(),!area.isFirstRowRelative(),!area.isFirstColRelative());
+        CellReference botRight = new CellReference(area.getLastRow(),area.getLastColumn(),!area.isLastRowRelative(),!area.isLastColRelative());
+        
+        if(isWholeColumnReference(topLeft, botRight)) {
+            return (new AreaReference(topLeft, botRight)).formatAsString();
+        }
+        return topLeft.formatAsString() + ":" + botRight.formatAsString(); 
+    }
     public String toString() {
         StringBuffer sb = new StringBuffer(64);
         sb.append(getClass().getName()).append(" [");

Modified: poi/branches/ooxml/src/java/org/apache/poi/hssf/util/HSSFColor.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/hssf/util/HSSFColor.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/hssf/util/HSSFColor.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/hssf/util/HSSFColor.java Fri May 23 02:48:23 2008
@@ -15,16 +15,16 @@
    limitations under the License.
 ==================================================================== */
 
-
 package org.apache.poi.hssf.util;
 
+import java.lang.reflect.Field;
 import java.util.Hashtable;
 
 import org.apache.poi.ss.usermodel.Color;
 
 /**
  * Intends to provide support for the very evil index to triplet issue and
- * will likely replace the color contants interface for HSSF 2.0.
+ * will likely replace the color constants interface for HSSF 2.0.
  * This class contains static inner class members for representing colors.
  * Each color has an index (for the standard palette in Excel (tm) ),
  * native (RGB) triplet and string triplet.  The string triplet is as the
@@ -35,14 +35,10 @@
  * @author  Andrew C. Oliver (acoliver at apache dot org)
  * @author  Brian Sanders (bsanders at risklabs dot com) - full default color palette
  */
-
-public class HSSFColor implements Color
-{
-    private final static int PALETTE_SIZE = 56;
-    private final static int DISTINCT_COLOR_COUNT = 46;
+public class HSSFColor implements Color {
+    // TODO make subclass instances immutable
 
     /** Creates a new instance of HSSFColor */
-
     public HSSFColor()
     {
     }
@@ -54,87 +50,86 @@
      * it takes to create it once per request but you will not hold onto it
      * if you have none of those requests.
      *
-     * @return a hashtable containing all colors mapped to their excel-style 
-     * pallette index
+     * @return a hashtable containing all colors keyed by <tt>Integer</tt> excel-style palette indexes
      */
     public final static Hashtable getIndexHash() {
 
-        Hashtable hash = new Hashtable(PALETTE_SIZE);
+        return createColorsByIndexMap();
+    }
 
-        hash.put(new Integer(HSSFColor.BLACK.index), new HSSFColor.BLACK());
-        hash.put(new Integer(HSSFColor.BROWN.index), new HSSFColor.BROWN());
-        hash.put(new Integer(HSSFColor.OLIVE_GREEN.index),
-                 new HSSFColor.OLIVE_GREEN());
-        hash.put(new Integer(HSSFColor.DARK_GREEN.index), new HSSFColor.DARK_GREEN());
-        hash.put(new Integer(HSSFColor.DARK_TEAL.index), new HSSFColor.DARK_TEAL());
-        hash.put(new Integer(HSSFColor.DARK_BLUE.index), new HSSFColor.DARK_BLUE());
-        hash.put(new Integer(HSSFColor.DARK_BLUE.index2), new HSSFColor.DARK_BLUE());
-        hash.put(new Integer(HSSFColor.INDIGO.index), new HSSFColor.INDIGO());
-        hash.put(new Integer(HSSFColor.GREY_80_PERCENT.index),
-                 new HSSFColor.GREY_80_PERCENT());
-        hash.put(new Integer(HSSFColor.ORANGE.index), new HSSFColor.ORANGE());
-        hash.put(new Integer(HSSFColor.DARK_YELLOW.index),
-                 new HSSFColor.DARK_YELLOW());
-        hash.put(new Integer(HSSFColor.GREEN.index), new HSSFColor.GREEN());
-        hash.put(new Integer(HSSFColor.TEAL.index), new HSSFColor.TEAL());
-        hash.put(new Integer(HSSFColor.TEAL.index2), new HSSFColor.TEAL());
-        hash.put(new Integer(HSSFColor.BLUE.index), new HSSFColor.BLUE());
-        hash.put(new Integer(HSSFColor.BLUE.index2), new HSSFColor.BLUE());
-        hash.put(new Integer(HSSFColor.BLUE_GREY.index), new HSSFColor.BLUE_GREY());
-        hash.put(new Integer(HSSFColor.GREY_50_PERCENT.index),
-                 new HSSFColor.GREY_50_PERCENT());
-        hash.put(new Integer(HSSFColor.RED.index), new HSSFColor.RED());
-        hash.put(new Integer(HSSFColor.LIGHT_ORANGE.index),
-                 new HSSFColor.LIGHT_ORANGE());
-        hash.put(new Integer(HSSFColor.LIME.index), new HSSFColor.LIME());
-        hash.put(new Integer(HSSFColor.SEA_GREEN.index), new HSSFColor.SEA_GREEN());
-        hash.put(new Integer(HSSFColor.AQUA.index), new HSSFColor.AQUA());
-        hash.put(new Integer(HSSFColor.LIGHT_BLUE.index), new HSSFColor.LIGHT_BLUE());
-        hash.put(new Integer(HSSFColor.VIOLET.index), new HSSFColor.VIOLET());
-        hash.put(new Integer(HSSFColor.VIOLET.index2), new HSSFColor.VIOLET());
-        hash.put(new Integer(HSSFColor.GREY_40_PERCENT.index),
-                 new HSSFColor.GREY_40_PERCENT());
-        hash.put(new Integer(HSSFColor.PINK.index), new HSSFColor.PINK());
-        hash.put(new Integer(HSSFColor.PINK.index2), new HSSFColor.PINK());
-        hash.put(new Integer(HSSFColor.GOLD.index), new HSSFColor.GOLD());
-        hash.put(new Integer(HSSFColor.YELLOW.index), new HSSFColor.YELLOW());
-        hash.put(new Integer(HSSFColor.YELLOW.index2), new HSSFColor.YELLOW());
-        hash.put(new Integer(HSSFColor.BRIGHT_GREEN.index),
-                 new HSSFColor.BRIGHT_GREEN());
-        hash.put(new Integer(HSSFColor.BRIGHT_GREEN.index2),
-                 new HSSFColor.BRIGHT_GREEN());
-        hash.put(new Integer(HSSFColor.TURQUOISE.index), new HSSFColor.TURQUOISE());
-        hash.put(new Integer(HSSFColor.TURQUOISE.index2), new HSSFColor.TURQUOISE());
-        hash.put(new Integer(HSSFColor.DARK_RED.index), new HSSFColor.DARK_RED());
-        hash.put(new Integer(HSSFColor.DARK_RED.index2), new HSSFColor.DARK_RED());
-        hash.put(new Integer(HSSFColor.SKY_BLUE.index), new HSSFColor.SKY_BLUE());
-        hash.put(new Integer(HSSFColor.PLUM.index), new HSSFColor.PLUM());
-        hash.put(new Integer(HSSFColor.PLUM.index2), new HSSFColor.PLUM());
-        hash.put(new Integer(HSSFColor.GREY_25_PERCENT.index),
-                 new HSSFColor.GREY_25_PERCENT());
-        hash.put(new Integer(HSSFColor.ROSE.index), new HSSFColor.ROSE());
-        hash.put(new Integer(HSSFColor.LIGHT_YELLOW.index),
-                 new HSSFColor.LIGHT_YELLOW());
-        hash.put(new Integer(HSSFColor.LIGHT_GREEN.index),
-                 new HSSFColor.LIGHT_GREEN());
-        hash.put(new Integer(HSSFColor.LIGHT_TURQUOISE.index),
-                 new HSSFColor.LIGHT_TURQUOISE());
-        hash.put(new Integer(HSSFColor.LIGHT_TURQUOISE.index2),
-                 new HSSFColor.LIGHT_TURQUOISE());
-        hash.put(new Integer(HSSFColor.PALE_BLUE.index), new HSSFColor.PALE_BLUE());
-        hash.put(new Integer(HSSFColor.LAVENDER.index), new HSSFColor.LAVENDER());
-        hash.put(new Integer(HSSFColor.WHITE.index), new HSSFColor.WHITE());
-        hash.put(new Integer(HSSFColor.CORNFLOWER_BLUE.index),
-                 new HSSFColor.CORNFLOWER_BLUE());
-        hash.put(new Integer(HSSFColor.LEMON_CHIFFON.index),
-                 new HSSFColor.LEMON_CHIFFON());
-        hash.put(new Integer(HSSFColor.MAROON.index), new HSSFColor.MAROON());
-        hash.put(new Integer(HSSFColor.ORCHID.index), new HSSFColor.ORCHID());
-        hash.put(new Integer(HSSFColor.CORAL.index), new HSSFColor.CORAL());
-        hash.put(new Integer(HSSFColor.ROYAL_BLUE.index), new HSSFColor.ROYAL_BLUE());
-        hash.put(new Integer(HSSFColor.LIGHT_CORNFLOWER_BLUE.index),
-                 new HSSFColor.LIGHT_CORNFLOWER_BLUE());
-	return hash;
+    private static Hashtable createColorsByIndexMap() {
+        HSSFColor[] colors = getAllColors();
+        Hashtable result = new Hashtable(colors.length * 3 / 2);
+
+        for (int i = 0; i < colors.length; i++) {
+            HSSFColor color = colors[i];
+
+            Integer index1 = new Integer(color.getIndex());
+            if (result.containsKey(index1)) {
+                HSSFColor prevColor = (HSSFColor)result.get(index1);
+                throw new RuntimeException("Dup color index (" + index1
+                        + ") for colors (" + prevColor.getClass().getName()
+                        + "),(" + color.getClass().getName() + ")");
+            }
+            result.put(index1, color);
+        }
+
+        for (int i = 0; i < colors.length; i++) {
+            HSSFColor color = colors[i];
+            Integer index2 = getIndex2(color);
+            if (index2 == null) {
+                // most colors don't have a second index
+                continue;
+            }
+            if (result.containsKey(index2)) {
+                if (false) { // Many of the second indexes clash
+                    HSSFColor prevColor = (HSSFColor)result.get(index2);
+                    throw new RuntimeException("Dup color index (" + index2
+                            + ") for colors (" + prevColor.getClass().getName()
+                            + "),(" + color.getClass().getName() + ")");
+                }
+            }
+            result.put(index2, color);
+        }
+        return result;
+    }
+
+    private static Integer getIndex2(HSSFColor color) {
+
+        Field f;
+        try {
+            f = color.getClass().getDeclaredField("index2");
+        } catch (NoSuchFieldException e) {
+            // can happen because not all colors have a second index
+            return null;
+        }
+
+        Short s;
+        try {
+            s = (Short) f.get(color);
+        } catch (IllegalArgumentException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+        return new Integer(s.intValue());
+    }
+
+    private static HSSFColor[] getAllColors() {
+
+        return new HSSFColor[] {
+                new BLACK(), new BROWN(), new OLIVE_GREEN(), new DARK_GREEN(),
+                new DARK_TEAL(), new DARK_BLUE(), new INDIGO(), new GREY_80_PERCENT(),
+                new ORANGE(), new DARK_YELLOW(), new GREEN(), new TEAL(), new BLUE(),
+                new BLUE_GREY(), new GREY_50_PERCENT(), new RED(), new LIGHT_ORANGE(), new LIME(),
+                new SEA_GREEN(), new AQUA(), new LIGHT_BLUE(), new VIOLET(), new GREY_40_PERCENT(),
+                new PINK(), new GOLD(), new YELLOW(), new BRIGHT_GREEN(), new TURQUOISE(),
+                new DARK_RED(), new SKY_BLUE(), new PLUM(), new GREY_25_PERCENT(), new ROSE(),
+                new LIGHT_YELLOW(), new LIGHT_GREEN(), new LIGHT_TURQUOISE(), new PALE_BLUE(),
+                new LAVENDER(), new WHITE(), new CORNFLOWER_BLUE(), new LEMON_CHIFFON(),
+                new MAROON(), new ORCHID(), new CORAL(), new ROYAL_BLUE(),
+                new LIGHT_CORNFLOWER_BLUE(), new TAN(),
+        };
     }
 
     /**
@@ -144,73 +139,28 @@
      * it takes to create it once per request but you will not hold onto it
      * if you have none of those requests.
      *
-     * @return a hashtable containing all colors mapped to their gnumeric-like
-     * triplet string
+     * @return a hashtable containing all colors keyed by String gnumeric-like triplets
      */
-
     public final static Hashtable getTripletHash()
     {
-        Hashtable hash = new Hashtable(DISTINCT_COLOR_COUNT);
+        return createColorsByHexStringMap();
+    }
+
+    private static Hashtable createColorsByHexStringMap() {
+        HSSFColor[] colors = getAllColors();
+        Hashtable result = new Hashtable(colors.length * 3 / 2);
+
+        for (int i = 0; i < colors.length; i++) {
+            HSSFColor color = colors[i];
 
-        hash.put(HSSFColor.BLACK.hexString, new HSSFColor.BLACK());
-        hash.put(HSSFColor.BROWN.hexString, new HSSFColor.BROWN());
-        hash.put(HSSFColor.OLIVE_GREEN.hexString,
-                 new HSSFColor.OLIVE_GREEN());
-        hash.put(HSSFColor.DARK_GREEN.hexString, new HSSFColor.DARK_GREEN());
-        hash.put(HSSFColor.DARK_TEAL.hexString, new HSSFColor.DARK_TEAL());
-        hash.put(HSSFColor.DARK_BLUE.hexString, new HSSFColor.DARK_BLUE());
-        hash.put(HSSFColor.INDIGO.hexString, new HSSFColor.INDIGO());
-        hash.put(HSSFColor.GREY_80_PERCENT.hexString,
-                 new HSSFColor.GREY_80_PERCENT());
-        hash.put(HSSFColor.ORANGE.hexString, new HSSFColor.ORANGE());
-        hash.put(HSSFColor.DARK_YELLOW.hexString,
-                 new HSSFColor.DARK_YELLOW());
-        hash.put(HSSFColor.GREEN.hexString, new HSSFColor.GREEN());
-        hash.put(HSSFColor.TEAL.hexString, new HSSFColor.TEAL());
-        hash.put(HSSFColor.BLUE.hexString, new HSSFColor.BLUE());
-        hash.put(HSSFColor.BLUE_GREY.hexString, new HSSFColor.BLUE_GREY());
-        hash.put(HSSFColor.GREY_50_PERCENT.hexString,
-                 new HSSFColor.GREY_50_PERCENT());
-        hash.put(HSSFColor.RED.hexString, new HSSFColor.RED());
-        hash.put(HSSFColor.LIGHT_ORANGE.hexString,
-                 new HSSFColor.LIGHT_ORANGE());
-        hash.put(HSSFColor.LIME.hexString, new HSSFColor.LIME());
-        hash.put(HSSFColor.SEA_GREEN.hexString, new HSSFColor.SEA_GREEN());
-        hash.put(HSSFColor.AQUA.hexString, new HSSFColor.AQUA());
-        hash.put(HSSFColor.LIGHT_BLUE.hexString, new HSSFColor.LIGHT_BLUE());
-        hash.put(HSSFColor.VIOLET.hexString, new HSSFColor.VIOLET());
-        hash.put(HSSFColor.GREY_40_PERCENT.hexString,
-                 new HSSFColor.GREY_40_PERCENT());
-        hash.put(HSSFColor.PINK.hexString, new HSSFColor.PINK());
-        hash.put(HSSFColor.GOLD.hexString, new HSSFColor.GOLD());
-        hash.put(HSSFColor.YELLOW.hexString, new HSSFColor.YELLOW());
-        hash.put(HSSFColor.BRIGHT_GREEN.hexString,
-                 new HSSFColor.BRIGHT_GREEN());
-        hash.put(HSSFColor.TURQUOISE.hexString, new HSSFColor.TURQUOISE());
-        hash.put(HSSFColor.DARK_RED.hexString, new HSSFColor.DARK_RED());
-        hash.put(HSSFColor.SKY_BLUE.hexString, new HSSFColor.SKY_BLUE());
-        hash.put(HSSFColor.PLUM.hexString, new HSSFColor.PLUM());
-        hash.put(HSSFColor.GREY_25_PERCENT.hexString,
-                 new HSSFColor.GREY_25_PERCENT());
-        hash.put(HSSFColor.ROSE.hexString, new HSSFColor.ROSE());
-        hash.put(HSSFColor.LIGHT_YELLOW.hexString,
-                 new HSSFColor.LIGHT_YELLOW());
-        hash.put(HSSFColor.LIGHT_GREEN.hexString,
-                 new HSSFColor.LIGHT_GREEN());
-        hash.put(HSSFColor.LIGHT_TURQUOISE.hexString,
-                 new HSSFColor.LIGHT_TURQUOISE());
-        hash.put(HSSFColor.PALE_BLUE.hexString, new HSSFColor.PALE_BLUE());
-        hash.put(HSSFColor.LAVENDER.hexString, new HSSFColor.LAVENDER());
-        hash.put(HSSFColor.WHITE.hexString, new HSSFColor.WHITE());
-        hash.put(HSSFColor.CORNFLOWER_BLUE.hexString, new HSSFColor.CORNFLOWER_BLUE());
-        hash.put(HSSFColor.LEMON_CHIFFON.hexString, new HSSFColor.LEMON_CHIFFON());
-        hash.put(HSSFColor.MAROON.hexString, new HSSFColor.MAROON());
-        hash.put(HSSFColor.ORCHID.hexString, new HSSFColor.ORCHID());
-        hash.put(HSSFColor.CORAL.hexString, new HSSFColor.CORAL());
-        hash.put(HSSFColor.ROYAL_BLUE.hexString, new HSSFColor.ROYAL_BLUE());
-        hash.put(HSSFColor.LIGHT_CORNFLOWER_BLUE.hexString,
-                 new HSSFColor.LIGHT_CORNFLOWER_BLUE());
-        return hash;
+            String hexString = color.getHexString();
+            if (result.containsKey(hexString)) {
+                throw new RuntimeException("Dup color hexString (" + hexString
+                        + ") for color (" + color.getClass().getName() + ")");
+            }
+            result.put(hexString, color);
+        }
+        return result;
     }
 
     /**
@@ -1492,7 +1442,7 @@
             return hexString;
         }
     }
-    
+
     /**
      * Class CORNFLOWER_BLUE
      */
@@ -1521,8 +1471,8 @@
             return hexString;
         }
     }
-    
-    
+
+
     /**
      * Class LEMON_CHIFFON
      */
@@ -1551,7 +1501,7 @@
             return hexString;
         }
     }
-    
+
     /**
      * Class MAROON
      */
@@ -1580,7 +1530,7 @@
             return hexString;
         }
     }
-    
+
     /**
      * Class ORCHID
      */
@@ -1609,7 +1559,7 @@
             return hexString;
         }
     }
-    
+
     /**
      * Class CORAL
      */
@@ -1638,7 +1588,7 @@
             return hexString;
         }
     }
-    
+
     /**
      * Class ROYAL_BLUE
      */
@@ -1667,7 +1617,7 @@
             return hexString;
         }
     }
-    
+
     /**
      * Class LIGHT_CORNFLOWER_BLUE
      */
@@ -1696,19 +1646,19 @@
             return hexString;
         }
     }
-    
+
     /**
      * Special Default/Normal/Automatic color.
      * <p><i>Note:</i> This class is NOT in the default HashTables returned by HSSFColor.
      * The index is a special case which is interpreted in the various setXXXColor calls.
-     * 
+     *
      * @author Jason
      *
      */
     public final static class AUTOMATIC extends HSSFColor
     {
-    	private static HSSFColor instance = new AUTOMATIC();
-    	
+        private static HSSFColor instance = new AUTOMATIC();
+
         public final static short   index     = 0x40;
 
         public short getIndex()
@@ -1725,7 +1675,7 @@
         {
             return BLACK.hexString;
         }
-        
+
         public static HSSFColor getInstance() {
           return instance;
         }

Modified: poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/DateUtil.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/DateUtil.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/DateUtil.java (original)
+++ poi/branches/ooxml/src/java/org/apache/poi/ss/usermodel/DateUtil.java Fri May 23 02:48:23 2008
@@ -226,7 +226,9 @@
     	
     	// Otherwise, check it's only made up, in any case, of:
     	//  y m d h s - / , . :
-    	if(fs.matches("^[yYmMdDhHsS\\-/,. :]+$")) {
+    	// optionally followed by AM/PM
+    	// optionally followed by AM/PM
+    	if(fs.matches("^[yYmMdDhHsS\\-/,. :]+[ampAMP]*$")) {
     		return true;
     	}
     	

Modified: poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt (original)
+++ poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata-asGenerated.txt Fri May 23 02:48:23 2008
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 # Created by (org.apache.poi.hssf.record.formula.function.ExcelFileFormatDocFunctionExtractor)
-# from source file 'excelfileformat.odt' (size=355750, crc=0x2FAEA65A)
+# from source file 'excelfileformat.odt' (size=356107, md5=0x8f789cb6e75594caf068f8e193004ef4)
 #
 #Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )
 
@@ -37,7 +37,7 @@
 15	SIN	1	1	V	V		
 16	COS	1	1	V	V		
 17	TAN	1	1	V	V		
-18	ARCTAN	1	1	V	V		
+18	ATAN	1	1	V	V		
 19	PI	0	0	V	-		
 20	SQRT	1	1	V	V		
 21	EXP	1	1	V	V		
@@ -141,8 +141,8 @@
 169	COUNTA	0	30	V	R		
 183	PRODUCT	0	30	V	R		
 184	FACT	1	1	V	V		
-191	DPRODUCT	3	3	V	R R R		
-192	ISNONTEXT	1	1	V	V		
+189	DPRODUCT	3	3	V	R R R		
+190	ISNONTEXT	1	1	V	V		
 193	STDEVP	1	30	V	R		
 194	VARP	1	30	V	R		
 195	DSTDEVP	3	3	V	R R R		
@@ -184,6 +184,8 @@
 244	INFO	1	1	V	V		
 # New Built-In Sheet Functions in BIFF4
 14	FIXED	2	3	V	V V V		x
+204	USDOLLAR	1	2	V	V V		x
+215	DBCS	1	1	V	V		x
 216	RANK	2	3	V	V R V		
 247	DB	4	5	V	V V V V V		
 252	FREQUENCY	2	2	A	R R		

Modified: poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt (original)
+++ poi/branches/ooxml/src/resources/main/org/apache/poi/hssf/record/formula/function/functionMetadata.txt Fri May 23 02:48:23 2008
@@ -14,11 +14,9 @@
 # limitations under the License.
 
 # Created by (org.apache.poi.hssf.record.formula.function.ExcelFileFormatDocFunctionExtractor)
-# from source file 'excelfileformat.odt' (size=355750, crc=0x2FAEA65A)
+# from source file 'excelfileformat.odt' (size=356107, md5=0x8f789cb6e75594caf068f8e193004ef4)
 #
 #Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )
-#
-# + some manual edits !
 
 # Built-In Sheet Functions in BIFF2
 0	COUNT	0	30	V	R		
@@ -186,7 +184,7 @@
 244	INFO	1	1	V	V		
 # New Built-In Sheet Functions in BIFF4
 14	FIXED	2	3	V	V V V		x
-204	USDOLLAR	1	1	V	V		x
+204	USDOLLAR	1	2	V	V V		x
 215	DBCS	1	1	V	V		x
 216	RANK	2	3	V	V R V		
 247	DB	4	5	V	V V V V V		

Modified: poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java
URL: http://svn.apache.org/viewvc/poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java?rev=659485&r1=659484&r2=659485&view=diff
==============================================================================
--- poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java (original)
+++ poi/branches/ooxml/src/scratchpad/src/org/apache/poi/hdgf/HDGFDiagram.java Fri May 23 02:48:23 2008
@@ -18,6 +18,7 @@
 
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 
 import org.apache.poi.POIDocument;
 import org.apache.poi.hdgf.chunks.ChunkFactory;
@@ -27,6 +28,7 @@
 import org.apache.poi.hdgf.streams.Stream;
 import org.apache.poi.hdgf.streams.StringsStream;
 import org.apache.poi.hdgf.streams.TrailerStream;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.LittleEndian;
@@ -53,14 +55,17 @@
 	private PointerFactory ptrFactory;
 	
 	public HDGFDiagram(POIFSFileSystem fs) throws IOException {
-		super(fs);
+		this(fs.getRoot(), fs);
+	}
+	public HDGFDiagram(DirectoryNode dir, POIFSFileSystem fs) throws IOException {
+		super(dir, fs);
 		
 		DocumentEntry docProps =
-			(DocumentEntry)filesystem.getRoot().getEntry("VisioDocument");
+			(DocumentEntry)dir.getEntry("VisioDocument");
 
 		// Grab the document stream
 		_docstream = new byte[docProps.getSize()];
-		filesystem.createDocumentInputStream("VisioDocument").read(_docstream);
+		dir.createDocumentInputStream("VisioDocument").read(_docstream);
 		
 		// Read in the common POI streams
 		readProperties();
@@ -149,6 +154,10 @@
 		}
 	}
 	
+	public void write(OutputStream out) {
+		throw new IllegalStateException("Writing is not yet implemented, see http://poi.apache.org/hdgf/");
+	}
+	
 	/**
 	 * For testing only
 	 */



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