poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r806395 - in /poi/trunk/src: java/org/apache/poi/hssf/record/ java/org/apache/poi/ss/util/ testcases/org/apache/poi/hssf/record/ testcases/org/apache/poi/hssf/util/
Date Thu, 20 Aug 2009 23:25:10 GMT
Author: josh
Date: Thu Aug 20 23:25:10 2009
New Revision: 806395

URL: http://svn.apache.org/viewvc?rev=806395&view=rev
Log:
minor improvements to sheet name validation and identification of cell references vs defined
names

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java
    poi/trunk/src/java/org/apache/poi/ss/util/CellReference.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/TestBoundSheetRecord.java
    poi/trunk/src/testcases/org/apache/poi/hssf/util/TestCellReference.java

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=806395&r1=806394&r2=806395&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 Thu Aug 20 23:25:10
2009
@@ -54,10 +54,9 @@
 	/**
 	 * UTF8: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
 	 * 1 + 1 + len(str)
-	 * 
+	 *
 	 * UNICODE: sid + len + bof + flags + len(str) + unicode + str 2 + 2 + 4 + 2 +
 	 * 1 + 1 + 2 * len(str)
-	 * 
 	 */
 	public BoundSheetRecord(RecordInputStream in) {
 		field_1_position_of_BOF = in.readInt();
@@ -75,9 +74,8 @@
 	/**
 	 * set the offset in bytes of the Beginning of File Marker within the HSSF
 	 * Stream part of the POIFS file
-	 * 
-	 * @param pos
-	 *			offset in bytes
+	 *
+	 * @param pos offset in bytes
 	 */
 	public void setPositionOfBof(int pos) {
 		field_1_position_of_BOF = pos;
@@ -86,10 +84,10 @@
 	/**
 	 * Set the sheetname for this sheet.  (this appears in the tabs at the bottom)
 	 * @param sheetName the name of the sheet
-	 * @throws IllegalArgumentException if sheet name will cause excel to crash. 
+	 * @throws IllegalArgumentException if sheet name will cause excel to crash.
 	 */
 	public void setSheetname(String sheetName) {
-		
+
 		validateSheetName(sheetName);
 		field_5_sheetname = sheetName;
 		field_4_isMultibyteUnicode = StringUtil.hasMultibyte(sheetName) ?  1 : 0;
@@ -117,10 +115,14 @@
 					// all other chars OK
 					continue;
 			}
-			throw new IllegalArgumentException("Invalid char (" + ch 
+			throw new IllegalArgumentException("Invalid char (" + ch
 					+ ") found at index (" + i + ") in sheet name '" + sheetName + "'");
 		}
- 	}
+		if (sheetName.charAt(0) == '\'' || sheetName.charAt(len-1) == '\'') {
+			throw new IllegalArgumentException("Invalid sheet name '" + sheetName
+					+ "'. Sheet names must not begin or end with (').");
+		}
+	}
 
 	/**
 	 * get the offset in bytes of the Beginning of File Marker within the HSSF Stream part of
the POIFS file
@@ -154,7 +156,7 @@
 		buffer.append("[/BOUNDSHEET]\n");
 		return buffer.toString();
 	}
-	
+
 	protected int getDataSize() {
 		return 8 + field_5_sheetname.length() * (isMultibyte() ? 2 : 1);
 	}
@@ -179,33 +181,33 @@
 	}
 
 	/**
-	 * Is the sheet hidden? Different from very hidden 
+	 * Is the sheet hidden? Different from very hidden
 	 */
 	public boolean isHidden() {
 		return hiddenFlag.isSet(field_2_option_flags);
 	}
 
 	/**
-	 * Is the sheet hidden? Different from very hidden 
+	 * Is the sheet hidden? Different from very hidden
 	 */
 	public void setHidden(boolean hidden) {
 		field_2_option_flags = hiddenFlag.setBoolean(field_2_option_flags, hidden);
 	}
 
 	/**
-	 * Is the sheet very hidden? Different from (normal) hidden 
+	 * Is the sheet very hidden? Different from (normal) hidden
 	 */
 	public boolean isVeryHidden() {
 		return veryHiddenFlag.isSet(field_2_option_flags);
 	}
 
 	/**
-	 * Is the sheet very hidden? Different from (normal) hidden 
+	 * Is the sheet very hidden? Different from (normal) hidden
 	 */
 	public void setVeryHidden(boolean veryHidden) {
 		field_2_option_flags = veryHiddenFlag.setBoolean(field_2_option_flags, veryHidden);
 	}
-	
+
 	/**
 	 * Converts a List of {@link BoundSheetRecord}s to an array and sorts by the position of
their
 	 * BOFs.

Modified: poi/trunk/src/java/org/apache/poi/ss/util/CellReference.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/util/CellReference.java?rev=806395&r1=806394&r2=806395&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/util/CellReference.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/util/CellReference.java Thu Aug 20 23:25:10 2009
@@ -32,11 +32,12 @@
 	/**
 	 * Used to classify identifiers found in formulas as cell references or not.
 	 */
-	public static final class NameType {
-		public static final int CELL = 1;
-		public static final int NAMED_RANGE = 2;
-		public static final int COLUMN = 3;
-		public static final int BAD_CELL_OR_NAMED_RANGE = -1;
+	public enum NameType {
+		CELL,
+		NAMED_RANGE,
+		COLUMN,
+		ROW,
+		BAD_CELL_OR_NAMED_RANGE;
 	}
 
 	/** The character ($) that signifies a row or column value is absolute instead of relative
*/
@@ -58,6 +59,11 @@
 	 */
 	private static final Pattern COLUMN_REF_PATTERN = Pattern.compile("\\$?([A-Za-z]+)");
 	/**
+	 * Matches a run of one or more digits.  The run of digits is group 1.
+	 * The text may optionally be prefixed with a single '$'.
+	 */
+	private static final Pattern ROW_REF_PATTERN = Pattern.compile("\\$?([0-9]+)");
+	/**
 	 * Named range names must start with a letter or underscore.  Subsequent characters may
include
 	 * digits or dot.  (They can even end in dot).
 	 */
@@ -176,7 +182,7 @@
 	 * Classifies an identifier as either a simple (2D) cell reference or a named range name
 	 * @return one of the values from <tt>NameType</tt>
 	 */
-	public static int classifyCellReference(String str, SpreadsheetVersion ssVersion) {
+	public static NameType classifyCellReference(String str, SpreadsheetVersion ssVersion) {
 		int len = str.length();
 		if (len < 1) {
 			throw new IllegalArgumentException("Empty string not allowed");
@@ -188,7 +194,7 @@
 			case '_':
 				break;
 			default:
-				if (!Character.isLetter(firstChar)) {
+				if (!Character.isLetter(firstChar) && !Character.isDigit(firstChar)) {
 					throw new IllegalArgumentException("Invalid first char (" + firstChar
 							+ ") of cell reference or named range.  Letter expected");
 				}
@@ -219,7 +225,7 @@
 		return NameType.NAMED_RANGE;
 	}
 
-	private static int validateNamedRangeName(String str, SpreadsheetVersion ssVersion) {
+	private static NameType validateNamedRangeName(String str, SpreadsheetVersion ssVersion)
{
 		Matcher colMatcher = COLUMN_REF_PATTERN.matcher(str);
 		if (colMatcher.matches()) {
 			String colStr = colMatcher.group(1);
@@ -227,6 +233,13 @@
 				return NameType.COLUMN;
 			}
 		}
+		Matcher rowMatcher = ROW_REF_PATTERN.matcher(str);
+		if (rowMatcher.matches()) {
+			String rowStr = rowMatcher.group(1);
+			if (isRowWithnRange(rowStr, ssVersion)) {
+				return NameType.ROW;
+			}
+		}
 		if (!NAMED_RANGE_NAME_PATTERN.matcher(str).matches()) {
 			return NameType.BAD_CELL_OR_NAMED_RANGE;
 		}
@@ -274,18 +287,7 @@
 		if (!isColumnWithnRange(colStr, ssVersion)) {
 			return false;
 		}
-
-		int rowNum = Integer.parseInt(rowStr);
-
-		if (rowNum < 0) {
-			throw new IllegalStateException("Invalid rowStr '" + rowStr + "'.");
-		}
-		if (rowNum == 0) {
-			// execution gets here because caller does first pass of discriminating
-			// potential cell references using a simplistic regex pattern.
-			return false;
-		}
-		return rowNum <= ssVersion.getMaxRows();
+		return isRowWithnRange(rowStr, ssVersion);
 	}
 
 	public static boolean isColumnWithnRange(String colStr, SpreadsheetVersion ssVersion) {
@@ -308,6 +310,20 @@
 		return true;
 	}
 
+	public static boolean isRowWithnRange(String rowStr, SpreadsheetVersion ssVersion) {
+		int rowNum = Integer.parseInt(rowStr);
+
+		if (rowNum < 0) {
+			throw new IllegalStateException("Invalid rowStr '" + rowStr + "'.");
+		}
+		if (rowNum == 0) {
+			// execution gets here because caller does first pass of discriminating
+			// potential cell references using a simplistic regex pattern.
+			return false;
+		}
+		return rowNum <= ssVersion.getMaxRows();
+	}
+
 	/**
 	 * Separates the row from the columns and returns an array of three Strings.  The first
element
 	 * is the sheet name. Only the first element may be null.  The second element in is the
column

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=806395&r1=806394&r2=806395&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 Thu Aug 20
23:25:10 2009
@@ -18,6 +18,10 @@
 package org.apache.poi.hssf.record;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.poi.util.HexRead;
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
@@ -32,67 +36,95 @@
 public final class TestBoundSheetRecord extends TestCase {
 
 
-    public void testRecordLength() {
-        BoundSheetRecord record = new BoundSheetRecord("Sheet1");
-        assertEquals(18, record.getRecordSize());
-    }
-
-    public void testWideRecordLength() {
-        BoundSheetRecord record = new BoundSheetRecord("Sheet\u20ac");
-        assertEquals(24, record.getRecordSize());
-    }
-
-    public void testName() {
-        BoundSheetRecord record = new BoundSheetRecord("1234567890223456789032345678904");
-
-        try {
-            record.setSheetname("s//*s");
-            throw new AssertionFailedError("Should have thrown IllegalArgumentException,
but didnt");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-    
-    public void testDeserializeUnicode() {
-       
-		byte[] data = {
-//			(byte)0x85, 0x00,       // sid
-//			0x1a, 0x00, 			// length
-			0x3C, 0x09, 0x00, 0x00, // bof
-			0x00, 0x00, 			// flags
-			0x09, 					// len( str )
-			0x01, 					// unicode
-			// <str>
-			0x21, 0x04, 0x42, 0x04, 0x40, 0x04, 
-			0x30, 0x04, 0x3D, 0x04, 0x38, 0x04,
-			0x47, 0x04, 0x3A, 0x04, 0x30, 0x04
-			// </str>
-		};
-	
-		RecordInputStream in = TestcaseRecordInputStream.create(BoundSheetRecord.sid, data);
+	public void testRecordLength() {
+		BoundSheetRecord record = new BoundSheetRecord("Sheet1");
+		assertEquals(18, record.getRecordSize());
+	}
+
+	public void testWideRecordLength() {
+		BoundSheetRecord record = new BoundSheetRecord("Sheet\u20ac");
+		assertEquals(24, record.getRecordSize());
+	}
+
+	public void testName() {
+		BoundSheetRecord record = new BoundSheetRecord("1234567890223456789032345678904");
+
+		try {
+			record.setSheetname("s//*s");
+			throw new AssertionFailedError("Should have thrown IllegalArgumentException, but didnt");
+		} catch (IllegalArgumentException e) {
+			// expected
+		}
+	}
+
+	public void testDeserializeUnicode() {
+
+		byte[] data = HexRead.readFromString(""
+			+ "85 00 1A 00" // sid, length
+			+ "3C 09 00 00" // bof
+			+ "00 00"// flags
+			+ "09 01" // str-len. unicode flag
+			// string data
+			+ "21 04 42 04 40 04"
+			+ "30 04 3D 04 38 04"
+			+ "47 04 3A 04 30 04"
+		);
+
+		RecordInputStream in = TestcaseRecordInputStream.create(data);
 		BoundSheetRecord bsr = new BoundSheetRecord(in);
 		// sheet name is unicode Russian for 'minor page'
 		assertEquals("\u0421\u0442\u0440\u0430\u043D\u0438\u0447\u043A\u0430", bsr.getSheetname());
-		
+
+		byte[] data2 = bsr.serialize();
+		assertTrue(Arrays.equals(data, data2));
+	}
+
+	public void testOrdering() {
+		BoundSheetRecord bs1 = new BoundSheetRecord("SheetB");
+		BoundSheetRecord bs2 = new BoundSheetRecord("SheetC");
+		BoundSheetRecord bs3 = new BoundSheetRecord("SheetA");
+		bs1.setPositionOfBof(11);
+		bs2.setPositionOfBof(33);
+		bs3.setPositionOfBof(22);
+
+		List<BoundSheetRecord> l = new ArrayList<BoundSheetRecord>();
+		l.add(bs1);
+		l.add(bs2);
+		l.add(bs3);
+
+		BoundSheetRecord[] r = BoundSheetRecord.orderByBofPosition(l);
+		assertEquals(3, r.length);
+		assertEquals(bs1, r[0]);
+		assertEquals(bs3, r[1]);
+		assertEquals(bs2, r[2]);
 	}
 
-    public void testOrdering() {
-    	BoundSheetRecord bs1 = new BoundSheetRecord("SheetB");
-    	BoundSheetRecord bs2 = new BoundSheetRecord("SheetC");
-    	BoundSheetRecord bs3 = new BoundSheetRecord("SheetA");
-    	bs1.setPositionOfBof(11);
-    	bs2.setPositionOfBof(33);
-    	bs3.setPositionOfBof(22);
-
-    	ArrayList l = new ArrayList();
-    	l.add(bs1);
-    	l.add(bs2);
-    	l.add(bs3);
-
-    	BoundSheetRecord[] r = BoundSheetRecord.orderByBofPosition(l);
-    	assertEquals(3, r.length);
-    	assertEquals(bs1, r[0]);
-    	assertEquals(bs3, r[1]);
-    	assertEquals(bs2, r[2]);
-    }
+	public void testValidNames() {
+		confirmValid("Sheet1", true);
+		confirmValid("O'Brien's sales", true);
+		confirmValid(" data # ", true);
+		confirmValid("data $1.00", true);
+
+		confirmValid("data?", false);
+		confirmValid("abc/def", false);
+		confirmValid("data[0]", false);
+		confirmValid("data*", false);
+		confirmValid("abc\\def", false);
+		confirmValid("'data", false);
+		confirmValid("data'", false);
+	}
+
+	private static void confirmValid(String sheetName, boolean expectedResult) {
+
+		try {
+			new BoundSheetRecord(sheetName);
+			if (!expectedResult) {
+				throw new AssertionFailedError("Expected sheet name '" + sheetName + "' to be invalid");
+			}
+		} catch (IllegalArgumentException e) {
+			if (expectedResult) {
+				throw new AssertionFailedError("Expected sheet name '" + sheetName + "' to be valid");
+			}
+		}
+	}
 }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/util/TestCellReference.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/util/TestCellReference.java?rev=806395&r1=806394&r2=806395&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/util/TestCellReference.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/util/TestCellReference.java Thu Aug 20 23:25:10
2009
@@ -14,7 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 package org.apache.poi.hssf.util;
 
 
@@ -26,12 +26,12 @@
 
 
 public final class TestCellReference extends TestCase {
-    
+
     public void testAbsRef1(){
         CellReference cf = new CellReference("$B$5");
         confirmCell(cf, null, 4, 1, true, true, "$B$5");
     }
-    
+
     public void  testAbsRef2(){
         CellReference cf = new CellReference(4,1,true,true);
         confirmCell(cf, null, 4, 1, true, true, "$B$5");
@@ -41,17 +41,17 @@
         CellReference cf = new CellReference("B$5");
         confirmCell(cf, null, 4, 1, true, false, "B$5");
     }
-    
+
     public void  testAbsRef4(){
         CellReference cf = new CellReference(4,1,true,false);
         confirmCell(cf, null, 4, 1, true, false, "B$5");
     }
-    
+
     public void  testAbsRef5(){
         CellReference cf = new CellReference("$B5");
         confirmCell(cf, null, 4, 1, false, true, "$B5");
     }
-    
+
     public void  testAbsRef6(){
         CellReference cf = new CellReference(4,1,false,true);
         confirmCell(cf, null, 4, 1, false, true, "$B5");
@@ -61,27 +61,27 @@
         CellReference cf = new CellReference("B5");
         confirmCell(cf, null, 4, 1, false, false, "B5");
     }
-    
+
     public void  testAbsRef8(){
         CellReference cf = new CellReference(4,1,false,false);
         confirmCell(cf, null, 4, 1, false, false, "B5");
     }
-    
+
     public void testSpecialSheetNames() {
         CellReference cf;
         cf = new CellReference("'profit + loss'!A1");
         confirmCell(cf, "profit + loss", 0, 0, false, false, "'profit + loss'!A1");
-        
+
         cf = new CellReference("'O''Brien''s Sales'!A1");
         confirmCell(cf, "O'Brien's Sales", 0, 0, false, false, "'O''Brien''s Sales'!A1");
-        
+
         cf = new CellReference("'Amazing!'!A1");
         confirmCell(cf, "Amazing!", 0, 0, false, false, "'Amazing!'!A1");
     }
 
-    /* package */ static void confirmCell(CellReference cf, String expSheetName, int expRow,

+    /* package */ static void confirmCell(CellReference cf, String expSheetName, int expRow,
             int expCol, boolean expIsRowAbs, boolean expIsColAbs, String expText) {
-        
+
         assertEquals(expSheetName, cf.getSheetName());
         assertEquals("row index is wrong", expRow, cf.getRow());
         assertEquals("col index is wrong", expCol, cf.getCol());
@@ -103,9 +103,19 @@
         confirmNameType("A.1", NameType.NAMED_RANGE);
         confirmNameType("A1.", NameType.NAMED_RANGE);
     }
-    
-    private void confirmNameType(String ref, int expectedResult) {
-        int actualResult = CellReference.classifyCellReference(ref, SpreadsheetVersion.EXCEL97);
+
+    public void testClassificationOfRowReferences(){
+        confirmNameType("10", NameType.ROW);
+        confirmNameType("$10", NameType.ROW);
+        confirmNameType("65536", NameType.ROW);
+
+        confirmNameType("65537", NameType.BAD_CELL_OR_NAMED_RANGE);
+        confirmNameType("$100000", NameType.BAD_CELL_OR_NAMED_RANGE);
+        confirmNameType("$1$1", NameType.BAD_CELL_OR_NAMED_RANGE);
+    }
+
+    private void confirmNameType(String ref, NameType expectedResult) {
+        NameType actualResult = CellReference.classifyCellReference(ref, SpreadsheetVersion.EXCEL97);
         assertEquals(expectedResult, actualResult);
     }
 }



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


Mime
View raw message