poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r682225 [2/3] - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/record/aggregates/ java/org/apache/poi/hssf/record/formula/ java/org/apache/poi/hssf/u...
Date Sun, 03 Aug 2008 22:11:27 GMT
Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java?rev=682225&r1=682224&r2=682225&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java Sun Aug  3 15:11:26
2008
@@ -16,17 +16,12 @@
 ==================================================================== */
 
 
-
-/*
- * DateUtil.java
- *
- * Created on January 19, 2002, 9:30 AM
- */
 package org.apache.poi.hssf.usermodel;
 
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
+import java.util.regex.Pattern;
 
 /**
  * Contains methods for dealing with Excel dates.
@@ -38,17 +33,20 @@
  * @author  Alex Jacoby (ajacoby at gmail.com)
  * @author  Pavel Krupets (pkrupets at palmtreebusiness dot com)
  */
+public final class HSSFDateUtil {
+    private HSSFDateUtil() {
+        // no instances of this class
+    }
+    private static final int SECONDS_PER_MINUTE = 60;
+    private static final int MINUTES_PER_HOUR = 60;
+    private static final int HOURS_PER_DAY = 24;
+    private static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
 
-public class HSSFDateUtil
-{
-    private HSSFDateUtil()
-    {
-    }
+    private static final int    BAD_DATE         = -1;   // used to specify that date is
invalid
+    private static final long   DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L;
+
+    private static final Pattern TIME_SEPARATOR_PATTERN = Pattern.compile(":");
 
-    private static final int    BAD_DATE         =
-        -1;   // used to specify that date is invalid
-    private static final long   DAY_MILLISECONDS = 24 * 60 * 60 * 1000;
-    
     /**
      * Given a Date, converts it into a double representing its internal Excel representation,
      *   which is the number of days since 1/1/1900. Fractional days represent hours, minutes,
and seconds.
@@ -57,7 +55,7 @@
      * @param  date the Date
      */
     public static double getExcelDate(Date date) {
-    	return getExcelDate(date, false);
+        return getExcelDate(date, false);
     }
     /**
      * Given a Date, converts it into a double representing its internal Excel representation,
@@ -74,8 +72,8 @@
     }
     /**
      * Given a Date in the form of a Calendar, converts it into a double
-     *  representing its internal Excel representation, which is the 
-     *  number of days since 1/1/1900. Fractional days represent hours, 
+     *  representing its internal Excel representation, which is the
+     *  number of days since 1/1/1900. Fractional days represent hours,
      *  minutes, and seconds.
      *
      * @return Excel representation of Date (-1 if error - test for error by checking for
less than 0.1)
@@ -83,41 +81,40 @@
      * @param use1904windowing Should 1900 or 1904 date windowing be used?
      */
     public static double getExcelDate(Calendar date, boolean use1904windowing) {
-    	// Don't alter the supplied Calendar as we do our work
-    	return internalGetExcelDate( (Calendar)date.clone(), use1904windowing );
+        // Don't alter the supplied Calendar as we do our work
+        return internalGetExcelDate( (Calendar)date.clone(), use1904windowing );
     }
     private static double internalGetExcelDate(Calendar date, boolean use1904windowing) {
-        if ((!use1904windowing && date.get(Calendar.YEAR) < 1900) || 
-            (use1904windowing && date.get(Calendar.YEAR) < 1904)) 
+        if ((!use1904windowing && date.get(Calendar.YEAR) < 1900) ||
+            (use1904windowing && date.get(Calendar.YEAR) < 1904))
         {
             return BAD_DATE;
-        } else {
-	    // Because of daylight time saving we cannot use
-	    //     date.getTime() - calStart.getTimeInMillis()
-	    // as the difference in milliseconds between 00:00 and 04:00
-	    // can be 3, 4 or 5 hours but Excel expects it to always
-	    // be 4 hours.
-	    // E.g. 2004-03-28 04:00 CEST - 2004-03-28 00:00 CET is 3 hours
-	    // and 2004-10-31 04:00 CET - 2004-10-31 00:00 CEST is 5 hours
-            double fraction = (((date.get(Calendar.HOUR_OF_DAY) * 60
-                                 + date.get(Calendar.MINUTE)
-                                ) * 60 + date.get(Calendar.SECOND)
-                               ) * 1000 + date.get(Calendar.MILLISECOND)
-                              ) / ( double ) DAY_MILLISECONDS;
-            Calendar calStart = dayStart(date);
-            
-            double value = fraction + absoluteDay(calStart, use1904windowing);
-            
-            if (!use1904windowing && value >= 60) {
-                value++;
-            } else if (use1904windowing) {
-                value--;
-            }
-            
-            return value;
         }
+        // Because of daylight time saving we cannot use
+        //     date.getTime() - calStart.getTimeInMillis()
+        // as the difference in milliseconds between 00:00 and 04:00
+        // can be 3, 4 or 5 hours but Excel expects it to always
+        // be 4 hours.
+        // E.g. 2004-03-28 04:00 CEST - 2004-03-28 00:00 CET is 3 hours
+        // and 2004-10-31 04:00 CET - 2004-10-31 00:00 CEST is 5 hours
+        double fraction = (((date.get(Calendar.HOUR_OF_DAY) * 60
+                             + date.get(Calendar.MINUTE)
+                            ) * 60 + date.get(Calendar.SECOND)
+                           ) * 1000 + date.get(Calendar.MILLISECOND)
+                          ) / ( double ) DAY_MILLISECONDS;
+        Calendar calStart = dayStart(date);
+
+        double value = fraction + absoluteDay(calStart, use1904windowing);
+
+        if (!use1904windowing && value >= 60) {
+            value++;
+        } else if (use1904windowing) {
+            value--;
+        }
+
+        return value;
     }
-    
+
     /**
      *  Given an Excel date with using 1900 date windowing, and
      *   converts it to a java.util.Date.
@@ -130,13 +127,13 @@
      *  <code>Europe/Copenhagen</code>, on 2004-03-28 the minute after
      *  01:59 CET is 03:00 CEST, if the excel date represents a time between
      *  02:00 and 03:00 then it is converted to past 03:00 summer time
-     *  
+     *
      *  @param date  The Excel date.
      *  @return Java representation of the date, or null if date is not a valid Excel date
      *  @see java.util.TimeZone
      */
     public static Date getJavaDate(double date) {
-    	return getJavaDate(date, false);
+        return getJavaDate(date, false);
     }
     /**
      *  Given an Excel date with either 1900 or 1904 date windowing,
@@ -158,94 +155,90 @@
      *  @see java.util.TimeZone
      */
     public static Date getJavaDate(double date, boolean use1904windowing) {
-        if (isValidExcelDate(date)) {
-            int startYear = 1900;
-            int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't
-            int wholeDays = (int)Math.floor(date);
-            if (use1904windowing) {
-                startYear = 1904;
-                dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day
-            }
-            else if (wholeDays < 61) {
-                // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists
-                // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation
-                dayAdjust = 0;
-            }
-            GregorianCalendar calendar = new GregorianCalendar(startYear,0,
-                                                     wholeDays + dayAdjust);
-            int millisecondsInDay = (int)((date - Math.floor(date)) * 
-                                          DAY_MILLISECONDS + 0.5);
-            calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
-            return calendar.getTime();
-        }
-        else {
+        if (!isValidExcelDate(date)) {
             return null;
         }
+        int startYear = 1900;
+        int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't
+        int wholeDays = (int)Math.floor(date);
+        if (use1904windowing) {
+            startYear = 1904;
+            dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day
+        }
+        else if (wholeDays < 61) {
+            // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists
+            // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation
+            dayAdjust = 0;
+        }
+        GregorianCalendar calendar = new GregorianCalendar(startYear,0,
+                                                 wholeDays + dayAdjust);
+        int millisecondsInDay = (int)((date - Math.floor(date)) *
+                                      DAY_MILLISECONDS + 0.5);
+        calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
+        return calendar.getTime();
     }
-    
+
     /**
      * Given a format ID and its format String, will check to see if the
      *  format represents a date format or not.
      * Firstly, it will check to see if the format ID corresponds to an
-     *  internal excel date format (eg most US date formats) 
+     *  internal excel date format (eg most US date formats)
      * If not, it will check to see if the format string only contains
      *  date formatting characters (ymd-/), which covers most
      *  non US date formats.
-     *  
+     *
      * @param formatIndex The index of the format, eg from ExtendedFormatRecord.getFormatIndex
      * @param formatString The format string, eg from FormatRecord.getFormatString
      * @see #isInternalDateFormat(int)
      */
     public static boolean isADateFormat(int formatIndex, String formatString) {
-    	// First up, is this an internal date format?
-    	if(isInternalDateFormat(formatIndex)) {
-    		return true;
-    	}
-    	
-    	// If we didn't get a real string, it can't be
-    	if(formatString == null || formatString.length() == 0) {
-    		return false;
-    	}
-    	
-    	String fs = formatString;
-    	
-    	// Translate \- into just -, before matching
-    	fs = fs.replaceAll("\\\\-","-");
-    	// And \, into ,
-    	fs = fs.replaceAll("\\\\,",",");
-    	// And '\ ' into ' '
-    	fs = fs.replaceAll("\\\\ "," ");
-    	
-    	// If it end in ;@, that's some crazy dd/mm vs mm/dd
-    	//  switching stuff, which we can ignore
-    	fs = fs.replaceAll(";@", "");
-    	
-    	// If it starts with [$-...], then could be a date, but
-    	//  who knows what that starting bit is all about
-    	fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");
-    	
-    	// If it starts with something like [Black] or [Yellow],
-    	//  then it could be a date
-    	fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");
-    	
-    	// Otherwise, check it's only made up, in any case, of:
-    	//  y m d h s - / , . :
-    	// optionally followed by AM/PM
-    	if(fs.matches("^[yYmMdDhHsS\\-/,. :]+[ampAMP/]*$")) {
-    		return true;
-    	}
-    	
-    	return false;
+        // First up, is this an internal date format?
+        if(isInternalDateFormat(formatIndex)) {
+            return true;
+        }
+
+        // If we didn't get a real string, it can't be
+        if(formatString == null || formatString.length() == 0) {
+            return false;
+        }
+
+        String fs = formatString;
+
+        // Translate \- into just -, before matching
+        fs = fs.replaceAll("\\\\-","-");
+        // And \, into ,
+        fs = fs.replaceAll("\\\\,",",");
+        // And '\ ' into ' '
+        fs = fs.replaceAll("\\\\ "," ");
+
+        // If it end in ;@, that's some crazy dd/mm vs mm/dd
+        //  switching stuff, which we can ignore
+        fs = fs.replaceAll(";@", "");
+
+        // If it starts with [$-...], then could be a date, but
+        //  who knows what that starting bit is all about
+        fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");
+
+        // If it starts with something like [Black] or [Yellow],
+        //  then it could be a date
+        fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");
+
+        // Otherwise, check it's only made up, in any case, of:
+        //  y m d h s - / , . :
+        // optionally followed by AM/PM
+        if(fs.matches("^[yYmMdDhHsS\\-/,. :]+[ampAMP/]*$")) {
+            return true;
+        }
+
+        return false;
     }
 
     /**
      * Given a format ID this will check whether the format represents
      *  an internal excel date format or not.
-     * @see #isADateFormat(int, java.lang.String)  
+     * @see #isADateFormat(int, java.lang.String)
      */
     public static boolean isInternalDateFormat(int format) {
-      boolean retval =false;
-
             switch(format) {
                 // Internal Date Formats as described on page 427 in
                 // Microsoft Excel Dev's Kit...
@@ -261,27 +254,22 @@
                 case 0x2d:
                 case 0x2e:
                 case 0x2f:
-                    retval = true;
-                    break;
-                    
-                default:
-                    retval = false;
-                    break;
+                    return true;
             }
-       return retval;
+       return false;
     }
 
     /**
      *  Check if a cell contains a date
-     *  Since dates are stored internally in Excel as double values 
-     *  we infer it is a date if it is formatted as such. 
+     *  Since dates are stored internally in Excel as double values
+     *  we infer it is a date if it is formatted as such.
      *  @see #isADateFormat(int, String)
      *  @see #isInternalDateFormat(int)
      */
     public static boolean isCellDateFormatted(HSSFCell cell) {
         if (cell == null) return false;
         boolean bDate = false;
-        
+
         double d = cell.getNumericCellValue();
         if ( HSSFDateUtil.isValidExcelDate(d) ) {
             HSSFCellStyle style = cell.getCellStyle();
@@ -302,7 +290,7 @@
     public static boolean isCellInternalDateFormatted(HSSFCell cell) {
         if (cell == null) return false;
         boolean bDate = false;
-        
+
         double d = cell.getNumericCellValue();
         if ( HSSFDateUtil.isValidExcelDate(d) ) {
             HSSFCellStyle style = cell.getCellStyle();
@@ -344,7 +332,7 @@
      *
      * @return    days  number of days in years prior to yr.
      * @param     yr    a year (1900 < yr < 4000)
-     * @param use1904windowing 
+     * @param use1904windowing
      * @exception IllegalArgumentException if year is outside of range.
      */
 
@@ -353,16 +341,16 @@
         if ((!use1904windowing && yr < 1900) || (use1904windowing && yr
< 1900)) {
             throw new IllegalArgumentException("'year' must be 1900 or greater");
         }
-        
+
         int yr1  = yr - 1;
         int leapDays =   yr1 / 4   // plus julian leap days in prior years
                        - yr1 / 100 // minus prior century years
-                       + yr1 / 400 // plus years divisible by 400 
+                       + yr1 / 400 // plus years divisible by 400
                        - 460;      // leap days in previous 1900 years
-        
+
         return 365 * (yr - (use1904windowing ? 1904 : 1900)) + leapDays;
     }
-    
+
     // set HH:MM:SS fields of cal to 00:00:00:000
     private static Calendar dayStart(final Calendar cal)
     {
@@ -377,5 +365,95 @@
         return cal;
     }
 
-    // ---------------------------------------------------------------------------------------------------------
+
+    private static final class FormatException extends Exception {
+        public FormatException(String msg) {
+            super(msg);
+        }
+    }
+
+    /**
+     * Converts a string of format "HH:MM" or "HH:MM:SS" to its (Excel) numeric equivalent
+     *
+     * @return a double between 0 and 1 representing the fraction of the day
+     */
+    public static double convertTime(String timeStr) {
+        try {
+            return convertTimeInternal(timeStr);
+        } catch (FormatException e) {
+            String msg = "Bad time format '" + timeStr
+                + "' expected 'HH:MM' or 'HH:MM:SS' - " + e.getMessage();
+            throw new IllegalArgumentException(msg);
+        }
+    }
+    private static double convertTimeInternal(String timeStr) throws FormatException {
+        int len = timeStr.length();
+        if (len < 4 || len > 8) {
+            throw new FormatException("Bad length");
+        }
+        String[] parts = TIME_SEPARATOR_PATTERN.split(timeStr);
+
+        String secStr;
+        switch (parts.length) {
+            case 2: secStr = "00"; break;
+            case 3: secStr = parts[2]; break;
+            default:
+                throw new FormatException("Expected 2 or 3 fields but got (" + parts.length
+ ")");
+        }
+        String hourStr = parts[0];
+        String minStr = parts[1];
+        int hours = parseInt(hourStr, "hour", HOURS_PER_DAY);
+        int minutes = parseInt(minStr, "minute", MINUTES_PER_HOUR);
+        int seconds = parseInt(secStr, "second", SECONDS_PER_MINUTE);
+
+        double totalSeconds = seconds + (minutes + (hours) * 60) * 60;
+        return totalSeconds / (SECONDS_PER_DAY);
+    }
+    /**
+     * Converts a string of format "YYYY/MM/DD" to its (Excel) numeric equivalent
+     *
+     * @return a double representing the (integer) number of days since the start of the
Excel epoch
+     */
+    public static Date parseYYYYMMDDDate(String dateStr) {
+        try {
+            return parseYYYYMMDDDateInternal(dateStr);
+        } catch (FormatException e) {
+            String msg = "Bad time format " + dateStr
+                + " expected 'YYYY/MM/DD' - " + e.getMessage();
+            throw new IllegalArgumentException(msg);
+        }
+    }
+    private static Date parseYYYYMMDDDateInternal(String timeStr) throws FormatException
{
+        if(timeStr.length() != 10) {
+            throw new FormatException("Bad length");
+        }
+
+        String yearStr = timeStr.substring(0, 4);
+        String monthStr = timeStr.substring(5, 7);
+        String dayStr = timeStr.substring(8, 10);
+        int year = parseInt(yearStr, "year", Short.MIN_VALUE, Short.MAX_VALUE);
+        int month = parseInt(monthStr, "month", 1, 12);
+        int day = parseInt(dayStr, "day", 1, 31);
+
+        Calendar cal = new GregorianCalendar(year, month-1, day, 0, 0, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        return cal.getTime();
+    }
+    private static int parseInt(String strVal, String fieldName, int rangeMax) throws FormatException
{
+        return parseInt(strVal, fieldName, 0, rangeMax-1);
+    }
+
+    private static int parseInt(String strVal, String fieldName, int lowerLimit, int upperLimit)
throws FormatException {
+        int result;
+        try {
+            result = Integer.parseInt(strVal);
+        } catch (NumberFormatException e) {
+            throw new FormatException("Bad int format '" + strVal + "' for " + fieldName
+ " field");
+        }
+        if (result < lowerLimit || result > upperLimit) {
+            throw new FormatException(fieldName + " value (" + result
+                    + ") is outside the allowable range(0.." + upperLimit + ")");
+        }
+        return result;
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=682225&r1=682224&r2=682225&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Sun Aug  3 15:11:26 2008
@@ -38,7 +38,6 @@
 import org.apache.poi.hssf.record.aggregates.DataValidityTable;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.record.formula.RefPtg;
-import org.apache.poi.hssf.util.HSSFDataValidation;
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.hssf.util.Region;
 import org.apache.poi.util.POILogFactory;
@@ -382,7 +381,8 @@
        }
        DataValidityTable dvt = sheet.getOrCreateDataValidityTable();
 
-       dvt.addDataValidation(dataValidation, workbook);
+       DVRecord dvRecord = dataValidation.createDVRecord(workbook);
+       dvt.addDataValidation(dvRecord);
     }
 
 

Added: poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddress.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddress.java?rev=682225&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddress.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddress.java Sun Aug  3 15:11:26
2008
@@ -0,0 +1,130 @@
+/* ====================================================================
+   Copyright 2002-2004   Apache Software Foundation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.util;
+
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'
+ * 
+ * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
+ */
+public final class CellRangeAddress {
+	private static final int ENCODED_SIZE = 8;
+
+	private int _firstRow;
+	private int _firstCol;
+	private int _lastRow;
+	private int _lastCol;
+
+	/*
+	 * TODO - replace other incarnations of 'Cell Range Address' throughout POI:
+	 * org.apache.poi.hssf.util.CellRange
+	 * org.apache.poi.hssf.record.cf.CellRange
+	 * org.apache.poi.hssf.util.HSSFCellRangeAddress.AddrStructure
+	 * org.apache.poi.hssf.record.MergeCellsRecord.MergedRegion
+	 * org.apache.poi.hssf.record.SelectionRecord.Reference
+	 * 
+	 */
+	
+	public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
+		_firstRow = firstRow;
+		_lastRow = lastRow;
+		_firstCol = firstCol;
+		_lastCol = lastCol;
+	}
+
+	public CellRangeAddress(RecordInputStream in) {
+		if (in.remaining() < ENCODED_SIZE) {
+			// Ran out of data
+			throw new RuntimeException("Ran out of data reading CellRangeAddress");
+		} 
+		_firstRow = in.readUShort();
+		_lastRow = in.readUShort();
+		_firstCol = in.readUShort();
+		_lastCol = in.readUShort();
+	}
+
+	/**
+	 * @return column number for the upper left hand corner
+	 */
+	public int getFirstColumn() {
+		return _firstCol;
+	}
+
+	/**
+	 * @return row number for the upper left hand corner
+	 */
+	public int getFirstRow() {
+		return _firstRow;
+	}
+
+	/**
+	 * @return column number for the lower right hand corner
+	 */
+	public int getLastColumn() {
+		return _lastCol;
+	}
+
+	/**
+	 * @return row number for the lower right hand corner
+	 */
+	public int getLastRow() {
+		return _lastRow;
+	}
+
+	/**
+	 * @param _firstCol column number for the upper left hand corner
+	 */
+	public void setFirstColumn(int firstCol) {
+		_firstCol = firstCol;
+	}
+
+	/**
+	 * @param rowFrom row number for the upper left hand corner
+	 */
+	public void setFirstRow(int firstRow) {
+		_firstRow = firstRow;
+	}
+
+	/**
+	 * @param colTo column number for the lower right hand corner
+	 */
+	public void setLastColumn(int lastCol) {
+		_lastCol = lastCol;
+	}
+
+	/**
+	 * @param rowTo row number for the lower right hand corner
+	 */
+	public void setLastRow(int lastRow) {
+		_lastRow = lastRow;
+	}
+
+	/* package */ int serialize(byte[] data, int offset) {
+		LittleEndian.putUShort(data, offset + 0, _firstRow);
+		LittleEndian.putUShort(data, offset + 2, _lastRow);
+		LittleEndian.putUShort(data, offset + 4, _firstCol);
+		LittleEndian.putUShort(data, offset + 6, _lastCol);
+		return ENCODED_SIZE;
+	}
+
+	public static int getEncodedSize(int numberOfItems) {
+		return numberOfItems * ENCODED_SIZE;
+	}
+}
\ No newline at end of file

Copied: poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java (from r681759,
poi/trunk/src/java/org/apache/poi/hssf/util/HSSFCellRangeAddress.java)
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java?p2=poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java&p1=poi/trunk/src/java/org/apache/poi/hssf/util/HSSFCellRangeAddress.java&r1=681759&r2=682225&rev=682225&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/util/HSSFCellRangeAddress.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java Sun Aug  3 15:11:26
2008
@@ -16,254 +16,102 @@
 
 package org.apache.poi.hssf.util;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.poi.hssf.record.RecordInputStream;
 import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
-import java.util.ArrayList;
 
 /**
- * <p>Title: HSSFCellRangeAddress</p>
- * <p>Description:
- *          Implementation of the cell range address lists,like is described in
- *          OpenOffice.org's Excel Documentation .
- *          In BIFF8 there is a common way to store absolute cell range address
- *          lists in several records (not formulas). A cell range address list
- *          consists of a field with the number of ranges and the list of the range
- *          addresses. Each cell range address (called an ADDR structure) contains
- *          4 16-bit-values.</p>
- * <p>Copyright: Copyright (c) 2004</p>
- * <p>Company: </p>
+ * Implementation of the cell range address lists,like is described
+ * in OpenOffice.org's Excel Documentation: excelfileformat.pdf sec 2.5.14 -
+ * 'Cell Range Address List'
+ * 
+ * In BIFF8 there is a common way to store absolute cell range address lists in
+ * several records (not formulas). A cell range address list consists of a field
+ * with the number of ranges and the list of the range addresses. Each cell
+ * range address (called an ADDR structure) contains 4 16-bit-values.
+ * </p>
+ * 
  * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
- * @version 2.0-pre
  */
+public final class CellRangeAddressList {
 
-public class HSSFCellRangeAddress
-{
-	private static POILogger logger = POILogFactory.getLogger(HSSFCellRangeAddress.class);
-	
-    /**
-     * Number of following ADDR structures
-     */
-    private short             field_addr_number;
-
-    /**
-     * List of ADDR structures. Each structure represents a cell range
-     */
-    private ArrayList         field_regions_list;
-
-    public HSSFCellRangeAddress()
-    {
-
-    }
-
-    /**
-     * Construct a new HSSFCellRangeAddress object and sets its fields appropriately .
-     * Even this isn't an Excel record , I kept the same behavior for reading/writing
-     * the object's data as for a regular record .
-     * 
-     * @param in the RecordInputstream to read the record from
-     */
-    public HSSFCellRangeAddress(RecordInputStream in)
-    {
-        this.fillFields(in);
-    }
-
-    public void fillFields(RecordInputStream in)
-    {
-        this.field_addr_number = in.readShort(); 
-		this.field_regions_list = new ArrayList(this.field_addr_number);
-
-		for (int k = 0; k < this.field_addr_number; k++)
-		{
-            short first_row = in.readShort(); 
-            short first_col = in.readShort();
-            
-            short last_row  = first_row;
-            short last_col  = first_col;
-            if(in.remaining() >= 4) {
-	            last_row  = in.readShort();
-	            last_col  = in.readShort();
-            } else {
-            	// Ran out of data
-            	// For now, issue a warning, finish, and 
-            	//  hope for the best....
-            	logger.log(POILogger.WARN, "Ran out of data reading cell references for DVRecord");
-            	k = this.field_addr_number;
-            }
+	/**
+	 * List of <tt>CellRangeAddress</tt>es. Each structure represents a cell range
+	 */
+	private final List _list;
 
-			AddrStructure region = new AddrStructure(first_row, first_col, last_row, last_col);
-			this.field_regions_list.add(region);
-		}
-    }
+	public CellRangeAddressList() {
+		_list = new ArrayList();
+	}
+	/**
+	 * Convenience constructor for creating a <tt>CellRangeAddressList</tt> with
a single 
+	 * <tt>CellRangeAddress</tt>.  Other <tt>CellRangeAddress</tt>es
may be added later.
+	 */
+	public CellRangeAddressList(int firstRow, int lastRow, int firstCol, int lastCol) {
+		this();
+		addCellRangeAddress(firstRow, firstCol, lastRow, lastCol);
+	}
 
-    /**
-     * Get the number of following ADDR structures.
-     * The number of this structures is automatically set when reading an Excel file
-     * and/or increased when you manually add a new ADDR structure .
-     * This is the reason there isn't a set method for this field .
-     * @return number of ADDR structures
-     */
-    public short getADDRStructureNumber()
-    {
-        return this.field_addr_number;
-    }
-
-    /**
-     * Add an ADDR structure .
-     * @param first_row - the upper left hand corner's row
-     * @param first_col - the upper left hand corner's col
-     * @param last_row  - the lower right hand corner's row
-     * @param last_col  - the lower right hand corner's col
-     * @return the index of this ADDR structure
-     */
-    public int addADDRStructure(short first_row, short first_col, short last_row, short last_col)
-    {
-        if (this.field_regions_list == null)
-        {
-            //just to be sure :-)
-            this.field_addr_number= 0;
-            this.field_regions_list = new ArrayList(10);
-        }
-        AddrStructure region = new AddrStructure(first_row, last_row, first_col, last_col);
-
-        this.field_regions_list.add(region);
-        this.field_addr_number++;
-        return this.field_addr_number;
-    }
-
-    /**
-     * Remove the ADDR structure stored at the passed in index
-     * @param index The ADDR structure's index
-     */
-    public void removeADDRStructureAt(int index)
-    {
-        this.field_regions_list.remove(index);
-        this.field_addr_number--;
-    }
-
-    /**
-     * return the ADDR structure at the given index.
-     * @return AddrStructure representing
-     */
-    public AddrStructure getADDRStructureAt(int index)
-    {
-        return ( AddrStructure ) this.field_regions_list.get(index);
-    }
-
-    public int serialize(int offset, byte [] data)
-    {
-        int pos  = 2;
-
-        LittleEndian.putShort(data, offset, this.getADDRStructureNumber());
-        for (int k = 0; k < this.getADDRStructureNumber(); k++)
-        {
-            AddrStructure region = this.getADDRStructureAt(k);
-            LittleEndian.putShort(data, offset + pos, region.getFirstRow());
-            pos += 2;
-            LittleEndian.putShort(data, offset + pos, region.getLastRow());
-            pos += 2;
-            LittleEndian.putShort(data, offset + pos, region.getFirstColumn());
-            pos += 2;
-            LittleEndian.putShort(data, offset + pos, region.getLastColumn());
-            pos += 2;
-        }
-        return this.getSize();
-    }
-
-    public int getSize()
-    {
-       return 2 + this.field_addr_number*8;
-    }
-
-    public class AddrStructure
-    {
-        private short _first_row;
-        private short _first_col;
-        private short _last_row;
-        private short _last_col;
-
-        public AddrStructure(short first_row, short last_row, short first_col, short last_col)
-        {
-            this._first_row = first_row;
-            this._last_row   = last_row;
-            this._first_col = first_col;
-            this._last_col   = last_col;
-        }
-
-		/**
-		 * get the upper left hand corner column number
-		 * @return column number for the upper left hand corner
-		 */
-		public short getFirstColumn()
-		{
-			return this._first_col;
-		}
+	/**
+	 * @param in the RecordInputstream to read the record from
+	 */
+	public CellRangeAddressList(RecordInputStream in) {
+		int nItems = in.readUShort();
+		_list = new ArrayList(nItems);
 
-		/**
-		 * get the upper left hand corner row number
-		 * @return row number for the upper left hand corner
-		 */
-		public short getFirstRow()
-		{
-			return this._first_row;
+		for (int k = 0; k < nItems; k++) {
+			_list.add(new CellRangeAddress(in));
 		}
+	}
 
-		/**
-		 * get the lower right hand corner column number
-		 * @return column number for the lower right hand corner
-		 */
-		public short getLastColumn()
-		{
-			return this._last_col;
-		}
+	/**
+	 * Get the number of following ADDR structures. The number of this
+	 * structures is automatically set when reading an Excel file and/or
+	 * increased when you manually add a new ADDR structure . This is the reason
+	 * there isn't a set method for this field .
+	 * 
+	 * @return number of ADDR structures
+	 */
+	public int getADDRStructureNumber() {
+		return _list.size();
+	}
 
-		/**
-		 * get the lower right hand corner row number
-		 * @return row number for the lower right hand corner
-		 */
-		public short getLastRow()
-		{
-			return this._last_row;
-		}
+	/**
+	 * Add an ADDR structure .
+	 * 
+	 * @param firstRow - the upper left hand corner's row
+	 * @param firstCol - the upper left hand corner's col
+	 * @param lastRow - the lower right hand corner's row
+	 * @param lastCol - the lower right hand corner's col
+	 * @return the index of this ADDR structure
+	 */
+	public void addCellRangeAddress(int firstRow, int firstCol, int lastRow, int lastCol) {
+		CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
+		_list.add(region);
+	}
 
-		/**
-		 * set the upper left hand corner column number
-		 * @param this._first_col  column number for the upper left hand corner
-		 */
-		public void setFirstColumn(short first_col)
-		{
-			this._first_col = first_col;
-		}
+	/**
+	 * @return <tt>CellRangeAddress</tt> at the given index
+	 */
+	public CellRangeAddress getCellRangeAddress(int index) {
+		return (CellRangeAddress) _list.get(index);
+	}
 
-		/**
-		 * set the upper left hand corner row number
-		 * @param rowFrom  row number for the upper left hand corner
-		 */
-		public void setFirstRow(short first_row)
-		{
-			this._first_row = first_row;
-		}
+	public int serialize(int offset, byte[] data) {
+		int pos = 2;
 
-		/**
-		 * set the lower right hand corner column number
-		 * @param colTo  column number for the lower right hand corner
-		 */
-		public void setLastColumn(short last_col)
-		{
-			this._last_col = last_col;
+		int nItems = _list.size();
+		LittleEndian.putUShort(data, offset, nItems);
+		for (int k = 0; k < nItems; k++) {
+			CellRangeAddress region = (CellRangeAddress) _list.get(k);
+			pos += region.serialize(data, offset + pos);
 		}
+		return getSize();
+	}
 
-		/**
-		 * get the lower right hand corner row number
-		 * @param rowTo  row number for the lower right hand corner
-		 */
-		public void setLastRow(short last_row)
-		{
-			this._last_row = last_row;
-		}
+	public int getSize() {
+		return 2 + CellRangeAddress.getEncodedSize(_list.size());
 	}
 }
-
-

Propchange: poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: poi/trunk/src/java/org/apache/poi/hssf/util/CellRangeAddressList.java
------------------------------------------------------------------------------
    svn:mergeinfo = 



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


Mime
View raw message