You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2008/09/30 00:04:21 UTC

svn commit: r700280 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/usermodel/ testcases/org/apache/poi/hssf/record/ testcases/org/apache/poi/hssf/usermodel/

Author: josh
Date: Mon Sep 29 15:04:20 2008
New Revision: 700280

URL: http://svn.apache.org/viewvc?rev=700280&view=rev
Log:
Fix for bug 45876 - allowed BoundSheetRecord to take sheet names longer than 31 chars

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/Workbook.java
    poi/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.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=700280&r1=700279&r2=700280&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Mon Sep 29 15:04:20 2008
@@ -37,6 +37,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.2-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45876 - fixed BoundSheetRecord to allow sheet names longer than 31 chars</action>
            <action dev="POI-DEVELOPERS" type="add">45890 - fixed HSSFSheet.shiftRows to also update conditional formats</action>
            <action dev="POI-DEVELOPERS" type="add">45865 modified Formula Parser/Evaluator to handle cross-worksheet formulas</action>
            <action dev="POI-DEVELOPERS" type="add">Optimised the FormulaEvaluator to take cell dependencies into account</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=700280&r1=700279&r2=700280&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Mon Sep 29 15:04:20 2008
@@ -34,6 +34,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.2-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">45876 - fixed BoundSheetRecord to allow sheet names longer than 31 chars</action>
            <action dev="POI-DEVELOPERS" type="add">45890 - fixed HSSFSheet.shiftRows to also update conditional formats</action>
            <action dev="POI-DEVELOPERS" type="add">45865 modified Formula Parser/Evaluator to handle cross-worksheet formulas</action>
            <action dev="POI-DEVELOPERS" type="add">Optimised the FormulaEvaluator to take cell dependencies into account</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java?rev=700280&r1=700279&r2=700280&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/Workbook.java Mon Sep 29 15:04:20 2008
@@ -55,6 +55,12 @@
  * @version 1.0-pre
  */
 public final class Workbook implements Model {
+    /**
+     * Excel silently truncates long sheet names to 31 chars.
+     * This constant is used to ensure uniqueness in the first 31 chars
+     */
+    private static final int MAX_SENSITIVE_SHEET_NAME_LEN = 31;
+
     private static final int   DEBUG       = POILogger.DEBUG;
 
     /**
@@ -488,32 +494,43 @@
 
     /**
      * sets the name for a given sheet.  If the boundsheet record doesn't exist and
-     * its only one more than we have, go ahead and create it.  If its > 1 more than
+     * its only one more than we have, go ahead and create it.  If it's > 1 more than
      * we have, except
      *
      * @param sheetnum the sheet number (0 based)
      * @param sheetname the name for the sheet
      */
-    public void setSheetName(int sheetnum, String sheetname ) {
+    public void setSheetName(int sheetnum, String sheetname) {
         checkSheets(sheetnum);
         BoundSheetRecord sheet = (BoundSheetRecord)boundsheets.get( sheetnum );
         sheet.setSheetname(sheetname);
     }
 
     /**
-     * Determines whether a workbook contains the provided sheet name.
+     * Determines whether a workbook contains the provided sheet name.  For the purpose of 
+     * comparison, long names are truncated to 31 chars.
      *
      * @param name the name to test (case insensitive match)
      * @param excludeSheetIdx the sheet to exclude from the check or -1 to include all sheets in the check.
      * @return true if the sheet contains the name, false otherwise.
      */
-    public boolean doesContainsSheetName( String name, int excludeSheetIdx )
-    {
-        for ( int i = 0; i < boundsheets.size(); i++ )
-        {
+    public boolean doesContainsSheetName(String name, int excludeSheetIdx) {
+        String aName = name;
+        if (aName.length() > MAX_SENSITIVE_SHEET_NAME_LEN) {
+            aName = aName.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN);
+        }
+        for (int i = 0; i < boundsheets.size(); i++) {
             BoundSheetRecord boundSheetRecord = getBoundSheetRec(i);
-            if (excludeSheetIdx != i && name.equalsIgnoreCase(boundSheetRecord.getSheetname()))
+            if (excludeSheetIdx == i) {
+                continue;
+            }
+            String bName = boundSheetRecord.getSheetname();
+            if (bName.length() > MAX_SENSITIVE_SHEET_NAME_LEN) {
+                bName = bName.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN);
+            }
+            if (aName.equalsIgnoreCase(bName)) {
                 return true;
+            }
         }
         return false;
     }
@@ -1954,9 +1971,9 @@
         return (short)getOrCreateLinkTable().checkExternSheet(sheetNumber);
     }
 
-	public int getExternalSheetIndex(String workbookName, String sheetName) {
-		return getOrCreateLinkTable().getExternalSheetIndex(workbookName, sheetName);
-	}
+    public int getExternalSheetIndex(String workbookName, String sheetName) {
+        return getOrCreateLinkTable().getExternalSheetIndex(workbookName, sheetName);
+    }
     
 
     /** gets the total number of names

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java?rev=700280&r1=700279&r2=700280&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java Mon Sep 29 15:04:20 2008
@@ -116,9 +116,8 @@
 			throw new IllegalArgumentException("sheetName must not be null");
 		}
 		int len = sheetName.length();
-		if (len < 1 || len > 31) {
-			throw new IllegalArgumentException("sheetName '" + sheetName 
-					+ "' is invalid - must be 1-30 characters long");
+		if (len < 1) {
+			throw new IllegalArgumentException("sheetName must not be empty string");
 		}
 		for (int i=0; i<len; i++) {
 			char ch = sheetName.charAt(i);

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=700280&r1=700279&r2=700280&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Mon Sep 29 15:04:20 2008
@@ -515,15 +515,17 @@
     }
 
     /**
-     * set the sheet name.
-     * Will throw IllegalArgumentException if the name is greater than 31 chars
-     * or contains /\?*[]
+     * Sets the sheet name.
+     * Will throw IllegalArgumentException if the name is duplicated or contains /\?*[]
+     * Note - Excel allows sheet names up to 31 chars in length but other applications allow more.
+     * Excel does not crash with names longer than 31 chars, but silently truncates such names to 
+     * 31 chars.  POI enforces uniqueness on the first 31 chars.
+     * 
      * @param sheetIx number (0 based)
      */
-    public void setSheetName(int sheetIx, String name)
-    {
-        if (workbook.doesContainsSheetName( name, sheetIx )) {
-            throw new IllegalArgumentException( "The workbook already contains a sheet with this name" );
+    public void setSheetName(int sheetIx, String name) {
+        if (workbook.doesContainsSheetName(name, sheetIx)) {
+            throw new IllegalArgumentException("The workbook already contains a sheet with this name");
         }
         validateSheetIndex(sheetIx);
         workbook.setSheetName(sheetIx, name);
@@ -726,14 +728,14 @@
      * create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and
      * returns the high level representation. Use this to create new sheets.
      *
-     * @param sheetname
-     *            sheetname to set for the sheet.
+     * @param sheetname the name for the new sheet. Note - certain length limits
+     * apply. See {@link #setSheetName(int, String)}.
+     *
      * @return HSSFSheet representing the new sheet.
      * @throws IllegalArgumentException
      *             if there is already a sheet present with a case-insensitive
      *             match for the specified name.
      */
-
     public HSSFSheet createSheet(String sheetname)
     {
         if (workbook.doesContainsSheetName( sheetname, _sheets.size() ))

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java?rev=700280&r1=700279&r2=700280&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java Mon Sep 29 15:04:20 2008
@@ -46,13 +46,6 @@
         BoundSheetRecord record = new BoundSheetRecord("1234567890223456789032345678904");
 
         try {
-            record.setSheetname("12345678902234567890323456789042");
-            throw new AssertionFailedError("Should have thrown IllegalArgumentException, but didnt");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
             record.setSheetname("s//*s");
             throw new AssertionFailedError("Should have thrown IllegalArgumentException, but didnt");
         } catch (IllegalArgumentException e) {

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java?rev=700280&r1=700279&r2=700280&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java Mon Sep 29 15:04:20 2008
@@ -891,4 +891,23 @@
 
         //TODO: check shapeId in the cloned sheet
     }
+    
+    /**
+     * POI now (Sep 2008) allows sheet names longer than 31 chars (for other apps besides Excel).
+     * Since Excel silently truncates to 31, make sure that POI enforces uniqueness on the first
+     * 31 chars. 
+     */
+    public void testLongSheetNames() {
+        HSSFWorkbook wb = new HSSFWorkbook();
+        final String SAME_PREFIX = "A123456789B123456789C123456789"; // 30 chars
+        
+        wb.createSheet(SAME_PREFIX + "Dxxxx");
+        try {
+            wb.createSheet(SAME_PREFIX + "Dyyyy"); // identical up to the 32nd char
+            throw new AssertionFailedError("Expected exception not thrown");
+        } catch (IllegalArgumentException e) {
+            assertEquals("The workbook already contains a sheet of this name", e.getMessage());
+        }
+        wb.createSheet(SAME_PREFIX + "Exxxx"); // OK - differs in the 31st char
+    }
 }



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