]> source.dussan.org Git - poi.git/commitdiff
More tweaks for bug 45404. Fixes for JDK 1.4, improved member scoping and formatting.
authorJosh Micich <josh@apache.org>
Mon, 28 Jul 2008 20:08:15 +0000 (20:08 +0000)
committerJosh Micich <josh@apache.org>
Mon, 28 Jul 2008 20:08:15 +0000 (20:08 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@680470 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java
src/testcases/org/apache/poi/hssf/usermodel/AllUserModelTests.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDataFormatter.java

index e186cf73c357dccff79c413b831c2c24e9fc2f13..67291a22f1f255bd6343893cc432f95d63c1f022 100644 (file)
@@ -68,78 +68,64 @@ import java.util.regex.Pattern;
  * can override the default format pattern with <code>
  * HSSFDataFormatter.setDefaultNumberFormat(Format)</code>. <b>Note:</b> the
  * default format will only be used when a Format cannot be created from the
- * cell's data format string.  
- * 
+ * cell's data format string.
+ *
  * @author James May (james dot may at fmr dot com)
  *
  */
-public class HSSFDataFormatter {
+public final class HSSFDataFormatter {
 
        /** Pattern to find a number format: "0" or  "#" */
-       protected Pattern numPattern;
-       
+       private static final Pattern numPattern = Pattern.compile("[0#]+");
+
        /** Pattern to find days of week as text "ddd...." */
-       protected Pattern daysAsText;
-       
+       private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE);
+
        /** Pattern to find "AM/PM" marker */
-       protected Pattern amPmPattern;
+       private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE);
 
        /** A regex to find patterns like [$$-1009] and [$�-452]. */
-       protected Pattern specialPatternGroup;
-       
+       private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
+
        /** <em>General</em> format for whole numbers. */
-       protected Format generalWholeNumFormat;
-       
+       private static final Format generalWholeNumFormat = new DecimalFormat("#");
+
        /** <em>General</em> format for decimal numbers. */
-       protected Format generalDecimalNumFormat;       
-       
+       private static final Format generalDecimalNumFormat = new DecimalFormat("#.##########");
+
        /** A default format to use when a number pattern cannot be parsed. */
-       protected Format defaultNumFormat;
-       
-       /** 
+       private Format defaultNumFormat;
+
+       /**
         * A map to cache formats.
         *  Map<String,Format> formats
         */
-       protected Map formats;
-       
+       private final Map formats;
 
        /**
         * Constructor
         */
        public HSSFDataFormatter() {
-               numPattern = Pattern.compile("[0#]+");
-               daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE);
-               amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE);
-               specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
-               generalWholeNumFormat =  new DecimalFormat("#");
-               generalDecimalNumFormat =  new DecimalFormat("#.##########");   
                formats = new HashMap();
-               
+
                // init built-in formats
-               init();
-       }
 
-       /**
-        * Initialize the formatter. Called after construction.
-        */
-       protected void init() {         
-               
-               ZipPlusFourFormat zipFormat = new ZipPlusFourFormat();
+               Format zipFormat = ZipPlusFourFormat.instance;
                addFormat("00000\\-0000", zipFormat);
                addFormat("00000-0000", zipFormat);
-               
-               PhoneFormat phoneFormat = new PhoneFormat();
+
+               Format phoneFormat = PhoneFormat.instance;
                // allow for format string variations
                addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
                addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat);
                addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
-               addFormat("###-####;(###) ###-####", phoneFormat);              
-               
-               SSNFormat ssnFormat = new SSNFormat();
-               addFormat("000\\-00\\-0000", ssnFormat);                
-               addFormat("000-00-0000", ssnFormat);                    
+               addFormat("###-####;(###) ###-####", phoneFormat);
+
+               Format ssnFormat = SSNFormat.instance;
+               addFormat("000\\-00\\-0000", ssnFormat);
+               addFormat("000-00-0000", ssnFormat);
        }
-       
+
        /**
         * Return a Format for the given cell if one exists, otherwise try to
         * create one. This method will return <code>null</code> if the any of the
@@ -149,15 +135,15 @@ public class HSSFDataFormatter {
         * <li>the style's data format string is null or empty</li>
         * <li>the format string cannot be recognized as either a number or date</li>
         * </ul>
-        * 
+        *
         * @param cell The cell to retrieve a Format for
         * @return A Format for the format String
         */
-       protected Format getFormat(HSSFCell cell) {
+       private Format getFormat(HSSFCell cell) {
                if ( cell.getCellStyle() == null) {
                        return null;
                }
-               
+
                int formatIndex = cell.getCellStyle().getDataFormat();
                String formatStr = cell.getCellStyle().getDataFormatString();
                if(formatStr == null || formatStr.trim().length() == 0) {
@@ -165,382 +151,375 @@ public class HSSFDataFormatter {
                }
                return getFormat(cell.getNumericCellValue(), formatIndex, formatStr);
        }
-       
+
        private Format getFormat(double cellValue, int formatIndex, String formatStr) {
                Format format = (Format)formats.get(formatStr);
                if (format != null) {
                        return format;
-               } else if (formatStr.equals("General")) {
+               }
+               if (formatStr.equals("General")) {
                        if (HSSFDataFormatter.isWholeNumber(cellValue)) {
                                return generalWholeNumFormat;
-                       } else {
-                               return generalDecimalNumFormat;
                        }
-               } else {
-                       format = createFormat(cellValue, formatIndex, formatStr);
-                       formats.put(formatStr, format);
-                       return format;
+                       return generalDecimalNumFormat;
                }
+               format = createFormat(cellValue, formatIndex, formatStr);
+               formats.put(formatStr, format);
+               return format;
        }
-       
+
        /**
         * Create and return a Format based on the format string from a  cell's
         * style. If the pattern cannot be parsed, return a default pattern.
-        * 
+        *
         * @param cell The Excel cell
         * @return A Format representing the excel format. May return null.
         */
-       protected Format createFormat(HSSFCell cell) {  
-               String sFormat = cell.getCellStyle().getDataFormatString();
-               
+       public Format createFormat(HSSFCell cell) {
+
                int formatIndex = cell.getCellStyle().getDataFormat();
                String formatStr = cell.getCellStyle().getDataFormatString();
-               return createFormat(cell.getNumericCellValue(), formatIndex, formatStr); 
+               return createFormat(cell.getNumericCellValue(), formatIndex, formatStr);
        }
-       
+
        private Format createFormat(double cellValue, int formatIndex, String sFormat) {
                // remove color formatting if present
                String formatStr = sFormat.replaceAll("\\[[a-zA-Z]*\\]", "");
-               
-               // Try to extract special characters like currency
-               // Need to re-create the matcher each time, as the string
-               //  will potentially change on each pass
-               Matcher m;
-               try {
-                       while((m = specialPatternGroup.matcher(formatStr)).find()) {
-                               String match = m.group();
-                               String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-'));
-                               if (symbol.indexOf('$') > -1) {
-                                       StringBuffer sb = new StringBuffer();
-                                       sb.append(symbol.substring(0, symbol.indexOf('$')));
-                                       sb.append('\\');
-                                       sb.append(symbol.substring(symbol.indexOf('$'), symbol.length()));
-                                       symbol = sb.toString();
-                               }
-                               formatStr = m.replaceAll(symbol);
+
+               // try to extract special characters like currency
+               Matcher m = specialPatternGroup.matcher(formatStr);
+               while(m.find()) {
+                       String match = m.group();
+                       String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-'));
+                       if (symbol.indexOf('$') > -1) {
+                               StringBuffer sb = new StringBuffer();
+                               sb.append(symbol.substring(0, symbol.indexOf('$')));
+                               sb.append('\\');
+                               sb.append(symbol.substring(symbol.indexOf('$'), symbol.length()));
+                               symbol = sb.toString();
                        }
-               } catch (Exception e) {
-                       return getDefaultFormat(cellValue);
+                       formatStr = m.replaceAll(symbol);
+                       m = specialPatternGroup.matcher(formatStr);
                }
-               
+
                if(formatStr == null || formatStr.trim().length() == 0) {
                        return getDefaultFormat(cellValue);
                }
 
-               Format returnVal = null;
-               StringBuffer sb = null;
-
-       if(HSSFDateUtil.isADateFormat(formatIndex,formatStr) &&
-                       HSSFDateUtil.isValidExcelDate(cellValue)) {
-               formatStr = formatStr.replaceAll("\\\\-","-");
-               formatStr = formatStr.replaceAll("\\\\,",",");
-               formatStr = formatStr.replaceAll("\\\\ "," ");
-               formatStr = formatStr.replaceAll(";@", "");
-               boolean hasAmPm = false;
-               Matcher amPmMatcher = amPmPattern.matcher(formatStr);
-               while (amPmMatcher.find()) {
-                       formatStr = amPmMatcher.replaceAll("a");
-                       hasAmPm = true;
-               }
-               
-               Matcher dateMatcher = daysAsText.matcher(formatStr);
-               if (dateMatcher.find()) {
-                               String match = dateMatcher.group(0);
-                               formatStr = dateMatcher.replaceAll(match.toUpperCase().replaceAll("D", "E"));
-               }
-               
-               // Convert excel date format to SimpleDateFormat.
-               // Excel uses lower case 'm' for both minutes and months.
-               // From Excel help:
-               /* 
-                         The "m" or "mm" code must appear immediately after the "h" or"hh"
-                         code or immediately before the "ss" code; otherwise, Microsoft
-                         Excel displays the month instead of minutes."
-                       */
-               
-               sb = new StringBuffer();
-               char[] chars = formatStr.toCharArray();
-               boolean mIsMonth = true;
-               List ms = new ArrayList();
-               for(int j=0; j<chars.length; j++) {
-                       char c = chars[j];
-                       if (c == 'h' || c == 'H') {
-                               mIsMonth = false;
-                               if (hasAmPm) {
-                                       sb.append('h');
-                               } else {
-                                       sb.append('H');
-                               }                               
-                       }
-                       else if (c == 'm') {
-                               if(mIsMonth) {
-                                       sb.append('M');
-                                       ms.add(
-                                                       new Integer(sb.length() -1)
-                                       );
-                               } else {
-                                       sb.append('m');
-                               }
-                       }
-                       else if (c == 's' || c == 'S') {
-                               sb.append('s');
-                               // if 'M' precedes 's' it should be minutes ('m') 
-                               for (int i = 0; i < ms.size(); i++) {
-                                       int index = ((Integer)ms.get(i)).intValue();
-                                       if (sb.charAt(index) == 'M') {
-                                               sb.replace(index, index+1, "m");
-                                       }
-                               }
-                               mIsMonth = true;
-                               ms.clear();
-                       }
-                       else if (Character.isLetter(c)) {
-                               mIsMonth = true;
-                               ms.clear();
-                               if (c == 'y' || c == 'Y') {
-                                       sb.append('y');
-                               }
-                               else if (c == 'd' || c == 'D') {
-                                       sb.append('d');                         
-                               }
-                               else {
-                                       sb.append(c);
-                               }                               
-                       }
-                       else {
-                               sb.append(c);
-                       }
-               }
-                       formatStr = sb.toString();
-                       
-                       try {
-                               returnVal = new SimpleDateFormat(formatStr);                            
-                       } catch(IllegalArgumentException iae) {
-                               
-                               // the pattern could not be parsed correctly,
-                               // so fall back to the default number format
-                               return getDefaultFormat(cellValue);
-                       }               
-                       
-               } else if (numPattern.matcher(formatStr).find()) {
-                       sb = new StringBuffer(formatStr);
-                       for (int i = 0; i < sb.length(); i++) {
-                               char c = sb.charAt(i);
-                               //handle (#,##0_);
-                               if (c == '(') {
-                                       int idx = sb.indexOf(")", i);
-                                       if (idx > -1 && sb.charAt(idx -1) == '_') {
-                                               sb.deleteCharAt(idx);
-                                               sb.deleteCharAt(idx - 1);
-                                               sb.deleteCharAt(i);
-                                               i--;
+
+               if(HSSFDateUtil.isADateFormat(formatIndex,formatStr) &&
+                               HSSFDateUtil.isValidExcelDate(cellValue)) {
+                       return createDateFormat(formatStr, cellValue);
+               }
+               if (numPattern.matcher(formatStr).find()) {
+                       return createNumberFormat(formatStr, cellValue);
+               }
+               // TODO - when does this occur?
+               return null;
+       }
+
+       private Format createDateFormat(String pFormatStr, double cellValue) {
+               String formatStr = pFormatStr;
+               formatStr = formatStr.replaceAll("\\\\-","-");
+               formatStr = formatStr.replaceAll("\\\\,",",");
+               formatStr = formatStr.replaceAll("\\\\ "," ");
+               formatStr = formatStr.replaceAll(";@", "");
+               boolean hasAmPm = false;
+               Matcher amPmMatcher = amPmPattern.matcher(formatStr);
+               while (amPmMatcher.find()) {
+                       formatStr = amPmMatcher.replaceAll("@");
+                       hasAmPm = true;
+                       amPmMatcher = amPmPattern.matcher(formatStr);
+               }
+               formatStr = formatStr.replaceAll("@", "a");
+
+
+               Matcher dateMatcher = daysAsText.matcher(formatStr);
+               if (dateMatcher.find()) {
+                       String match = dateMatcher.group(0);
+                       formatStr = dateMatcher.replaceAll(match.toUpperCase().replaceAll("D", "E"));
+               }
+
+               // Convert excel date format to SimpleDateFormat.
+               // Excel uses lower case 'm' for both minutes and months.
+               // From Excel help:
+               /*
+                 The "m" or "mm" code must appear immediately after the "h" or"hh"
+                 code or immediately before the "ss" code; otherwise, Microsoft
+                 Excel displays the month instead of minutes."
+               */
+
+               StringBuffer sb = new StringBuffer();
+               char[] chars = formatStr.toCharArray();
+               boolean mIsMonth = true;
+               List ms = new ArrayList();
+               for(int j=0; j<chars.length; j++) {
+                       char c = chars[j];
+                       if (c == 'h' || c == 'H') {
+                               mIsMonth = false;
+                               if (hasAmPm) {
+                                       sb.append('h');
+                               } else {
+                                       sb.append('H');
+                               }
+                       }
+                       else if (c == 'm') {
+                               if(mIsMonth) {
+                                       sb.append('M');
+                                       ms.add(
+                                                       new Integer(sb.length() -1)
+                                       );
+                               } else {
+                                       sb.append('m');
+                               }
+                       }
+                       else if (c == 's' || c == 'S') {
+                               sb.append('s');
+                               // if 'M' precedes 's' it should be minutes ('m')
+                               for (int i = 0; i < ms.size(); i++) {
+                                       int index = ((Integer)ms.get(i)).intValue();
+                                       if (sb.charAt(index) == 'M') {
+                                               sb.replace(index, index+1, "m");
                                        }
-                               } else if (c == ')' && i > 0 && sb.charAt(i - 1) == '_') {
-                                       sb.deleteCharAt(i);
-                                       sb.deleteCharAt(i - 1);
-                                       i--;
-                               // remove quotes and back slashes
-                               } else if (c == '\\' || c == '"') {
-                                       sb.deleteCharAt(i);
-                                       i--;
-                                       
-                               // for scientific/engineering notation
-                               } else if (c == '+' && i > 0 && sb.charAt(i - 1) == 'E') {
+                               }
+                               mIsMonth = true;
+                               ms.clear();
+                       }
+                       else if (Character.isLetter(c)) {
+                               mIsMonth = true;
+                               ms.clear();
+                               if (c == 'y' || c == 'Y') {
+                                       sb.append('y');
+                               }
+                               else if (c == 'd' || c == 'D') {
+                                       sb.append('d');
+                               }
+                               else {
+                                       sb.append(c);
+                               }
+                       }
+                       else {
+                               sb.append(c);
+                       }
+               }
+               formatStr = sb.toString();
+
+               try {
+                       return new SimpleDateFormat(formatStr);
+               } catch(IllegalArgumentException iae) {
+
+                       // the pattern could not be parsed correctly,
+                       // so fall back to the default number format
+                       return getDefaultFormat(cellValue);
+               }
+
+       }
+
+       private Format createNumberFormat(String formatStr, double cellValue) {
+               StringBuffer sb = new StringBuffer(formatStr);
+               for (int i = 0; i < sb.length(); i++) {
+                       char c = sb.charAt(i);
+                       //handle (#,##0_);
+                       if (c == '(') {
+                               int idx = sb.indexOf(")", i);
+                               if (idx > -1 && sb.charAt(idx -1) == '_') {
+                                       sb.deleteCharAt(idx);
+                                       sb.deleteCharAt(idx - 1);
                                        sb.deleteCharAt(i);
                                        i--;
-                               }                                                       
-                       }
-                       formatStr = sb.toString();
-                       try {
-                               returnVal = new DecimalFormat(formatStr);                               
-                       } catch(IllegalArgumentException iae) {
+                               }
+                       } else if (c == ')' && i > 0 && sb.charAt(i - 1) == '_') {
+                               sb.deleteCharAt(i);
+                               sb.deleteCharAt(i - 1);
+                               i--;
+                       // remove quotes and back slashes
+                       } else if (c == '\\' || c == '"') {
+                               sb.deleteCharAt(i);
+                               i--;
 
-                               // the pattern could not be parsed correctly,
-                               // so fall back to the default number format
-                               return getDefaultFormat(cellValue);
+                       // for scientific/engineering notation
+                       } else if (c == '+' && i > 0 && sb.charAt(i - 1) == 'E') {
+                               sb.deleteCharAt(i);
+                               i--;
                        }
                }
-               return returnVal;
+
+               try {
+                       return new DecimalFormat(sb.toString());
+               } catch(IllegalArgumentException iae) {
+
+                       // the pattern could not be parsed correctly,
+                       // so fall back to the default number format
+                       return getDefaultFormat(cellValue);
+               }
        }
-       
+
        /**
         * Return true if the double value represents a whole number
         * @param d the double value to check
-        * @return true if d is a whole number
+        * @return <code>true</code> if d is a whole number
         */
        private static boolean isWholeNumber(double d) {
                return d == Math.floor(d);
        }
-       
+
        /**
         * Returns a default format for a cell.
         * @param cell The cell
         * @return a default format
         */
-       protected Format getDefaultFormat(HSSFCell cell) {
+       public Format getDefaultFormat(HSSFCell cell) {
                return getDefaultFormat(cell.getNumericCellValue());
        }
        private Format getDefaultFormat(double cellValue) {
                // for numeric cells try user supplied default
                if (defaultNumFormat != null) {
                        return defaultNumFormat;
-                       
-                 // otherwise use general format       
-               } else if (isWholeNumber(cellValue)){
+
+                 // otherwise use general format
+               }
+               if (isWholeNumber(cellValue)){
                        return generalWholeNumFormat;
-               } else {
-                       return generalDecimalNumFormat;
                }
+               return generalDecimalNumFormat;
        }
-       
+
        /**
         * Returns the formatted value of an Excel date as a <tt>String</tt> based
         * on the cell's <code>DataFormat</code>. i.e. "Thursday, January 02, 2003"
         * , "01/02/2003" , "02-Jan" , etc.
-        * 
+        *
         * @param cell The cell
         * @return a formatted date string
-        */      
-    protected String getFormattedDateString(HSSFCell cell) {
-       Format dateFormat = getFormat(cell);
-       Date d = cell.getDateCellValue();
-       if (dateFormat != null) {
-               return dateFormat.format(d);
-       } else {
-               return d.toString();
-       }
-    }
-    
+        */
+       private String getFormattedDateString(HSSFCell cell) {
+               Format dateFormat = getFormat(cell);
+               Date d = cell.getDateCellValue();
+               if (dateFormat != null) {
+                       return dateFormat.format(d);
+               }
+               return d.toString();
+       }
+
        /**
         * Returns the formatted value of an Excel number as a <tt>String</tt>
         * based on the cell's <code>DataFormat</code>. Supported formats include
         * currency, percents, decimals, phone number, SSN, etc.:
         * "61.54%", "$100.00", "(800) 555-1234".
-        * 
+        *
         * @param cell The cell
         * @return a formatted number string
-        */ 
-    protected String getFormattedNumberString(HSSFCell cell) {
-       
-       Format numberFormat = getFormat(cell);
-       double d = cell.getNumericCellValue();
-       if (numberFormat != null) {
-               return numberFormat.format(new Double(d));
-       } else {
-               return String.valueOf(d);
-       }       
-    }
-
-    /**
-     * Formats the given raw cell value, based on the supplied
-     *  format index and string, according to excel style rules.
-     * @see #formatCellValue(HSSFCell)
-     */
-    public String formatRawCellContents(double value, int formatIndex, String formatString) {
-       // Is it a date?
-       if(HSSFDateUtil.isADateFormat(formatIndex,formatString) &&
-                       HSSFDateUtil.isValidExcelDate(value)) {
-               
-               Format dateFormat = getFormat(value, formatIndex, formatString);
-               Date d = HSSFDateUtil.getJavaDate(value);
-               if (dateFormat != null) {
-                       return dateFormat.format(d);
-               } else {
-                       return d.toString();
-               }
-       } else {
-               // Number
-               Format numberFormat = getFormat(value, formatIndex, formatString);
-               if (numberFormat != null) {
-                       return numberFormat.format(new Double(value));
-               } else {
-                       return String.valueOf(value);
-               }       
-       }
-    }
-    
+        */
+       private String getFormattedNumberString(HSSFCell cell) {
+
+               Format numberFormat = getFormat(cell);
+               double d = cell.getNumericCellValue();
+               if (numberFormat == null) {
+                       return String.valueOf(d);
+               }
+               return numberFormat.format(new Double(d));
+       }
+
+       /**
+        * Formats the given raw cell value, based on the supplied
+        *  format index and string, according to excel style rules.
+        * @see #formatCellValue(HSSFCell)
+        */
+       public String formatRawCellContents(double value, int formatIndex, String formatString) {
+               // Is it a date?
+               if(HSSFDateUtil.isADateFormat(formatIndex,formatString) &&
+                               HSSFDateUtil.isValidExcelDate(value)) {
+
+                       Format dateFormat = getFormat(value, formatIndex, formatString);
+                       Date d = HSSFDateUtil.getJavaDate(value);
+                       if (dateFormat == null) {
+                               return d.toString();
+                       }
+                       return dateFormat.format(d);
+               }
+               // else Number
+               Format numberFormat = getFormat(value, formatIndex, formatString);
+               if (numberFormat == null) {
+                       return String.valueOf(value);
+               }
+               return numberFormat.format(new Double(value));
+       }
+
        /**
         * <p>
         * Returns the formatted value of a cell as a <tt>String</tt> regardless
         * of the cell type. If the Excel format pattern cannot be parsed then the
-        * cell value will be formatted using a default format. 
+        * cell value will be formatted using a default format.
         * </p>
         * <p>When passed a null or blank cell, this method will return an empty
         * String (""). Formulas in formula type cells will not be evaluated.
         * </p>
-        * 
+        *
         * @param cell The cell
         * @return the formatted cell value as a String
         */
        public String formatCellValue(HSSFCell cell) {
                return formatCellValue(cell, null);
        }
-    
+
        /**
         * <p>
         * Returns the formatted value of a cell as a <tt>String</tt> regardless
         * of the cell type. If the Excel format pattern cannot be parsed then the
-        * cell value will be formatted using a default format. 
+        * cell value will be formatted using a default format.
         * </p>
         * <p>When passed a null or blank cell, this method will return an empty
         * String (""). Formula cells will be evaluated using the given
         * {@link HSSFFormulaEvaluator} if the evaluator is non-null. If the
         * evaluator is null, then the formula String will be returned. The caller
-        * is responsible for setting the currentRow on the evaluator, otherwise an
-        * IllegalArgumentException may be thrown.
+        * is responsible for setting the currentRow on the evaluator
         *</p>
-        * 
-        * @param cell The cell
+        *
+        * @param cell The cell (can be null)
         * @param evaluator The HSSFFormulaEvaluator (can be null)
         * @return a string value of the cell
-        * @throws IllegalArgumentException if cell type is <code>
-        * HSSFCell.CELL_TYPE_FORMULA</code> <b>and</b> evaluator is not null
-        * <b>and</b> the evlaluator's currentRow has not been set.
         */
-       public String formatCellValue(HSSFCell cell, 
+       public String formatCellValue(HSSFCell cell,
                        HSSFFormulaEvaluator evaluator) throws IllegalArgumentException {
 
-               String value = "";
                if (cell == null) {
-                       return value;
+                       return "";
                }
-               
+
                int cellType = cell.getCellType();
                if (evaluator != null && cellType == HSSFCell.CELL_TYPE_FORMULA) {
                        try {
                                cellType = evaluator.evaluateFormulaCell(cell);
-                       } catch (Throwable t) {
-                               throw new IllegalArgumentException("Did you forget to set the current" +
-                                               " row on the HSSFFormulaEvaluator?", t);
+                       } catch (RuntimeException e) {
+                               throw new RuntimeException("Did you forget to set the current" +
+                                               " row on the HSSFFormulaEvaluator?", e);
                        }
-               }               
+               }
                switch (cellType)
-        {
-            case HSSFCell.CELL_TYPE_FORMULA :
-               // should only occur if evaluator is null
-               value = cell.getCellFormula();
-                break;
-
-            case HSSFCell.CELL_TYPE_NUMERIC :
-               
-               if (HSSFDateUtil.isCellDateFormatted(cell)) {
-                       value = getFormattedDateString(cell);
-               } else {
-                       value = getFormattedNumberString(cell);
-               }
-                break;
-
-            case HSSFCell.CELL_TYPE_STRING :
-                value = cell.getRichStringCellValue().getString();
-                break;
-                
-            case HSSFCell.CELL_TYPE_BOOLEAN :
-               value = String.valueOf(cell.getBooleanCellValue());
-        }
-               return value;
+               {
+                       case HSSFCell.CELL_TYPE_FORMULA :
+                               // should only occur if evaluator is null
+                               return cell.getCellFormula();
+
+                       case HSSFCell.CELL_TYPE_NUMERIC :
+
+                               if (HSSFDateUtil.isCellDateFormatted(cell)) {
+                                       return getFormattedDateString(cell);
+                               }
+                               return getFormattedNumberString(cell);
+
+                       case HSSFCell.CELL_TYPE_STRING :
+                               return cell.getRichStringCellValue().getString();
+
+                       case HSSFCell.CELL_TYPE_BOOLEAN :
+                               return String.valueOf(cell.getBooleanCellValue());
+                       case HSSFCell.CELL_TYPE_BLANK :
+                               return "";
+               }
+               throw new RuntimeException("Unexpected celltype (" + cellType + ")");
        }
-               
-       
+
+
        /**
         * <p>
         * Sets a default number format to be used when the Excel format cannot be
@@ -554,7 +533,7 @@ public class HSSFDataFormatter {
         * numeric cell. Therefore the code in the format method should expect a
         * <code>Number</code> value.
         * </p>
-        * 
+        *
         * @param format A Format instance to be used as a default
         * @see java.text.Format#format
         */
@@ -568,8 +547,8 @@ public class HSSFDataFormatter {
                        }
                }
                defaultNumFormat = format;
-       }       
-       
+       }
+
        /**
         * Adds a new format to the available formats.
         * <p>
@@ -577,7 +556,7 @@ public class HSSFDataFormatter {
         * by <code>java.text.Format#format</code>) will be a double value from a
         * numeric cell. Therefore the code in the format method should expect a
         * <code>Number</code> value.
-        * </p>  
+        * </p>
         * @param excelFormatStr The data format string
         * @param format A Format instance
         */
@@ -586,24 +565,30 @@ public class HSSFDataFormatter {
        }
 
        // Some custom formats
-       
+
+       /**
+        * @return a <tt>DecimalFormat</tt> with parseIntegerOnly set <code>true</code>
+        */
+       /* package */ static DecimalFormat createIntegerOnlyFormat(String fmt) {
+               DecimalFormat result = new DecimalFormat(fmt);
+               result.setParseIntegerOnly(true);
+               return result;
+       }
        /**
         * Format class for Excel's SSN format. This class mimics Excel's built-in
         * SSN formatting.
-        * 
+        *
         * @author James May
         */
-       static class SSNFormat extends Format {
-               private DecimalFormat df;
-               
-               /** Constructor */
-               public SSNFormat() {
-                       df = new DecimalFormat("000000000");
-                       df.setParseIntegerOnly(true);
-               }
-               
+       private static final class SSNFormat extends Format {
+               public static final Format instance = new SSNFormat();
+               private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
+               private SSNFormat() {
+                       // enforce singleton
+               }
+
                /** Format a number as an SSN */
-               public String format(Number num) {
+               public static String format(Number num) {
                        String result = df.format(num);
                        StringBuffer sb = new StringBuffer();
                        sb.append(result.substring(0, 3)).append('-');
@@ -611,66 +596,60 @@ public class HSSFDataFormatter {
                        sb.append(result.substring(5, 9));
                        return sb.toString();
                }
-               
-               public StringBuffer format(Object obj, StringBuffer toAppendTo,
-                               FieldPosition pos) {
+
+               public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
                        return toAppendTo.append(format((Number)obj));
                }
-               
+
                public Object parseObject(String source, ParsePosition pos) {
                        return df.parseObject(source, pos);
                }
        }
-       
+
        /**
         * Format class for Excel Zip + 4 format. This class mimics Excel's
         * built-in formatting for Zip + 4.
         * @author James May
-        */     
-       static class ZipPlusFourFormat extends Format {
-               private DecimalFormat df;
-               
-               /** Constructor */
-               public ZipPlusFourFormat() {
-                       df = new DecimalFormat("000000000");
-                       df.setParseIntegerOnly(true);
-               }
-               
+        */
+       private static final class ZipPlusFourFormat extends Format {
+               public static final Format instance = new ZipPlusFourFormat();
+               private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
+               private ZipPlusFourFormat() {
+                       // enforce singleton
+               }
+
                /** Format a number as Zip + 4 */
-               public String format(Number num) {
+               public static String format(Number num) {
                        String result = df.format(num);
                        StringBuffer sb = new StringBuffer();
                        sb.append(result.substring(0, 5)).append('-');
                        sb.append(result.substring(5, 9));
                        return sb.toString();
                }
-               
-               public StringBuffer format(Object obj, StringBuffer toAppendTo,
-                               FieldPosition pos) {
+
+               public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
                        return toAppendTo.append(format((Number)obj));
                }
-               
+
                public Object parseObject(String source, ParsePosition pos) {
                        return df.parseObject(source, pos);
                }
-       }       
-       
+       }
+
        /**
         * Format class for Excel phone number format. This class mimics Excel's
         * built-in phone number formatting.
         * @author James May
-        */     
-       static class PhoneFormat extends Format {
-               private DecimalFormat df;
-
-               /** Constructor */
-               public PhoneFormat() {
-                       df = new DecimalFormat("##########");
-                       df.setParseIntegerOnly(true);
+        */
+       private static final class PhoneFormat extends Format {
+               public static final Format instance = new PhoneFormat();
+               private static final DecimalFormat df = createIntegerOnlyFormat("##########");
+               private PhoneFormat() {
+                       // enforce singleton
                }
-               
+
                /** Format a number as a phone number */
-               public String format(Number num) {
+               public static String format(Number num) {
                        String result = df.format(num);
                        StringBuffer sb = new StringBuffer();
                        String seg1, seg2, seg3;
@@ -678,28 +657,27 @@ public class HSSFDataFormatter {
                        if (len <= 4) {
                                return result;
                        }
-                       
+
                        seg3 = result.substring(len - 4, len);
-                       seg2 = result.substring(Math.max(0, len - 7), len - 4); 
+                       seg2 = result.substring(Math.max(0, len - 7), len - 4);
                        seg1 = result.substring(Math.max(0, len - 10), Math.max(0, len - 7));
-                       
+
                        if(seg1 != null && seg1.trim().length() > 0) {
                                sb.append('(').append(seg1).append(") ");
                        }
                        if(seg2 != null && seg2.trim().length() > 0) {
-                               sb.append(seg2).append('-'); 
+                               sb.append(seg2).append('-');
                        }
                        sb.append(seg3);
                        return sb.toString();
                }
-               
-               public StringBuffer format(Object obj, StringBuffer toAppendTo,
-                               FieldPosition pos) {
+
+               public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
                        return toAppendTo.append(format((Number)obj));
                }
-               
+
                public Object parseObject(String source, ParsePosition pos) {
                        return df.parseObject(source, pos);
                }
-       }       
+       }
 }
index 15a19c09121c9ae679415c61170aa68ae8c66acd..772a4fdfc781cfc9c88fa71c5d34686928651de3 100755 (executable)
@@ -44,6 +44,7 @@ public class AllUserModelTests {
                result.addTestSuite(TestHSSFClientAnchor.class);
                result.addTestSuite(TestHSSFComment.class);
                result.addTestSuite(TestHSSFConditionalFormatting.class);
+               result.addTestSuite(TestHSSFDataFormatter.class);
                result.addTestSuite(TestHSSFDateUtil.class);
                result.addTestSuite(TestHSSFHeaderFooter.class);
                result.addTestSuite(TestHSSFHyperlink.class);
index 39baedd8856d04c40cfd55db1cee4b760fdd457f..f865d6e494ed9f5c2833de32d55b18f0e84c819e 100644 (file)
@@ -25,141 +25,141 @@ import junit.framework.TestCase;
 
 /**
  * Unit tests for HSSFDataFormatter.java
- * 
+ *
  * @author James May (james dot may at fmr dot com)
  *
  */
-public class TestHSSFDataFormatter extends TestCase {
+public final class TestHSSFDataFormatter extends TestCase {
+
+       private final HSSFDataFormatter formatter;
+       private final HSSFWorkbook wb;
 
-       HSSFDataFormatter formatter;
-       HSSFWorkbook wb;
-       
        public TestHSSFDataFormatter() {
                // create the formatter to test
                formatter = new HSSFDataFormatter();
-               
+
                // create a workbook to test with
-           wb = new HSSFWorkbook();
-           HSSFSheet sheet = wb.createSheet();
-           HSSFDataFormat format = wb.createDataFormat();
-  
-           // create a row and put some cells in it
-           HSSFRow row = sheet.createRow((short)0);
-
-           // date value for July 8 1901 1:19 PM
-           double dateNum = 555.555;
-           
-           //valid date formats -- all should have "Jul" in output
-           String[] goodDatePatterns = new String[] {
-               "[$-F800]dddd\\,\\ mmmm\\ dd\\,\\ yyyy",
-               "mmm/d/yy\\ h:mm PM;@",
-               "mmmm/d/yy\\ h:mm;@",
-               "mmmm/d;@",
-               "mmmm/d/yy;@",
-               "mmm/dd/yy;@",
-               "[$-409]d\\-mmm;@",
-               "[$-409]d\\-mmm\\-yy;@",
-               "[$-409]dd\\-mmm\\-yy;@",
-               "[$-409]mmm\\-yy;@",
-               "[$-409]mmmm\\-yy;@",
-               "[$-409]mmmm\\ d\\,\\ yyyy;@",
-               "[$-409]mmm/d/yy\\ h:mm:ss;@",
-               "[$-409]mmmm/d/yy\\ h:mm:ss am;@",
-               "[$-409]mmmmm;@",
-               "[$-409]mmmmm\\-yy;@",
-               "mmmm/d/yyyy;@",
-               "[$-409]d\\-mmm\\-yyyy;@"
-           };
-           
-           // valid number formats
-           String[] goodNumPatterns = new String[] {
-                       "#,##0.0000",
-                       "#,##0;[Red]#,##0",
-                       "(#,##0.00_);(#,##0.00)",
-                       "($#,##0.00_);[Red]($#,##0.00)",
-                       "$#,##0.00",
-                       "[$�-809]#,##0.00",
-                       "[$�-2] #,##0.00",
-                       "0000.00000%",
-                       "0.000E+00",
-                       "0.00E+00",
-           };
-           
-           // invalid date formats -- will throw exception in DecimalFormat ctor
-           String[] badNumPatterns = new String[] {
-                       "#,#$'#0.0000",
-                       "'#','#ABC#0;##,##0",
-                       "000 '123 4'5'6 000",
-                       "#''0#0'1#10L16EE"
-           };      
-           
-           // create cells with good date patterns
-           for (int i = 0; i < goodDatePatterns.length; i++) {
-               HSSFCell cell = row.createCell((short) i);
-               cell.setCellValue(dateNum);
-               HSSFCellStyle cellStyle = wb.createCellStyle();
-               cellStyle.setDataFormat(format.getFormat(goodDatePatterns[i]));
-               cell.setCellStyle(cellStyle);
-           }
-           row = sheet.createRow(1);
-           
-           // create cells with num patterns
-           for (int i = 0; i < goodNumPatterns.length; i++) {
-               HSSFCell cell = row.createCell((short) i);
-               cell.setCellValue(-1234567890.12345);
-               HSSFCellStyle cellStyle = wb.createCellStyle();
-               cellStyle.setDataFormat(format.getFormat(goodNumPatterns[i]));
-               cell.setCellStyle(cellStyle);
-           }
-           row = sheet.createRow(2);
-           
-           // create cells with bad num patterns
-           for (int i = 0; i < badNumPatterns.length; i++) {
-               HSSFCell cell = row.createCell((short) i);
-               cell.setCellValue(1234567890.12345);
-               HSSFCellStyle cellStyle = wb.createCellStyle();
-               cellStyle.setDataFormat(format.getFormat(badNumPatterns[i]));
-               cell.setCellStyle(cellStyle);
-           }
-           
-           // Built in formats
-
-           { // Zip + 4 format
-               row = sheet.createRow(3);
-               HSSFCell cell = row.createCell((short) 0);
-               cell.setCellValue(123456789);
-               HSSFCellStyle cellStyle = wb.createCellStyle();
-               cellStyle.setDataFormat(format.getFormat("00000-0000"));
-               cell.setCellStyle(cellStyle);
-           }
-           
-           { // Phone number format
-               row = sheet.createRow(4);
-               HSSFCell cell = row.createCell((short) 0);
-               cell.setCellValue(5551234567D);
-               HSSFCellStyle cellStyle = wb.createCellStyle();
-               cellStyle.setDataFormat(format.getFormat("[<=9999999]###-####;(###) ###-####"));
-               cell.setCellStyle(cellStyle);
-           }
-           
-           { // SSN format
-               row = sheet.createRow(5);
-               HSSFCell cell = row.createCell((short) 0);
-               cell.setCellValue(444551234);
-               HSSFCellStyle cellStyle = wb.createCellStyle();
-               cellStyle.setDataFormat(format.getFormat("000-00-0000"));
-               cell.setCellStyle(cellStyle);
-           }
-           
-           { // formula cell
-               row = sheet.createRow(6);
-               HSSFCell cell = row.createCell((short) 0);
-               cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
-               cell.setCellFormula("SUM(12.25,12.25)/100");
-               HSSFCellStyle cellStyle = wb.createCellStyle();
-               cellStyle.setDataFormat(format.getFormat("##.00%;"));
-               cell.setCellStyle(cellStyle);
-           }       
+               wb = new HSSFWorkbook();
+               HSSFSheet sheet = wb.createSheet();
+               HSSFDataFormat format = wb.createDataFormat();
+
+               // create a row and put some cells in it
+               HSSFRow row = sheet.createRow(0);
+
+               // date value for July 8 1901 1:19 PM
+               double dateNum = 555.555;
+
+               //valid date formats -- all should have "Jul" in output
+               String[] goodDatePatterns ={
+                       "[$-F800]dddd\\,\\ mmmm\\ dd\\,\\ yyyy",
+                       "mmm/d/yy\\ h:mm PM;@",
+                       "mmmm/d/yy\\ h:mm;@",
+                       "mmmm/d;@",
+                       "mmmm/d/yy;@",
+                       "mmm/dd/yy;@",
+                       "[$-409]d\\-mmm;@",
+                       "[$-409]d\\-mmm\\-yy;@",
+                       "[$-409]dd\\-mmm\\-yy;@",
+                       "[$-409]mmm\\-yy;@",
+                       "[$-409]mmmm\\-yy;@",
+                       "[$-409]mmmm\\ d\\,\\ yyyy;@",
+                       "[$-409]mmm/d/yy\\ h:mm:ss;@",
+                       "[$-409]mmmm/d/yy\\ h:mm:ss am;@",
+                       "[$-409]mmmmm;@",
+                       "[$-409]mmmmm\\-yy;@",
+                       "mmmm/d/yyyy;@",
+                       "[$-409]d\\-mmm\\-yyyy;@"
+               };
+
+               // valid number formats
+               String[] goodNumPatterns = {
+                               "#,##0.0000",
+                               "#,##0;[Red]#,##0",
+                               "(#,##0.00_);(#,##0.00)",
+                               "($#,##0.00_);[Red]($#,##0.00)",
+                               "$#,##0.00",
+                               "[$�-809]#,##0.00",
+                               "[$�-2] #,##0.00",
+                               "0000.00000%",
+                               "0.000E+00",
+                               "0.00E+00",
+               };
+
+               // invalid date formats -- will throw exception in DecimalFormat ctor
+               String[] badNumPatterns = {
+                               "#,#$'#0.0000",
+                               "'#','#ABC#0;##,##0",
+                               "000 '123 4'5'6 000",
+                               "#''0#0'1#10L16EE"
+               };
+
+               // create cells with good date patterns
+               for (int i = 0; i < goodDatePatterns.length; i++) {
+                       HSSFCell cell = row.createCell((short) i);
+                       cell.setCellValue(dateNum);
+                       HSSFCellStyle cellStyle = wb.createCellStyle();
+                       cellStyle.setDataFormat(format.getFormat(goodDatePatterns[i]));
+                       cell.setCellStyle(cellStyle);
+               }
+               row = sheet.createRow(1);
+
+               // create cells with num patterns
+               for (int i = 0; i < goodNumPatterns.length; i++) {
+                       HSSFCell cell = row.createCell((short) i);
+                       cell.setCellValue(-1234567890.12345);
+                       HSSFCellStyle cellStyle = wb.createCellStyle();
+                       cellStyle.setDataFormat(format.getFormat(goodNumPatterns[i]));
+                       cell.setCellStyle(cellStyle);
+               }
+               row = sheet.createRow(2);
+
+               // create cells with bad num patterns
+               for (int i = 0; i < badNumPatterns.length; i++) {
+                       HSSFCell cell = row.createCell((short) i);
+                       cell.setCellValue(1234567890.12345);
+                       HSSFCellStyle cellStyle = wb.createCellStyle();
+                       cellStyle.setDataFormat(format.getFormat(badNumPatterns[i]));
+                       cell.setCellStyle(cellStyle);
+               }
+
+               // Built in formats
+
+               { // Zip + 4 format
+                       row = sheet.createRow(3);
+                       HSSFCell cell = row.createCell((short) 0);
+                       cell.setCellValue(123456789);
+                       HSSFCellStyle cellStyle = wb.createCellStyle();
+                       cellStyle.setDataFormat(format.getFormat("00000-0000"));
+                       cell.setCellStyle(cellStyle);
+               }
+
+               { // Phone number format
+                       row = sheet.createRow(4);
+                       HSSFCell cell = row.createCell((short) 0);
+                       cell.setCellValue(5551234567D);
+                       HSSFCellStyle cellStyle = wb.createCellStyle();
+                       cellStyle.setDataFormat(format.getFormat("[<=9999999]###-####;(###) ###-####"));
+                       cell.setCellStyle(cellStyle);
+               }
+
+               { // SSN format
+                       row = sheet.createRow(5);
+                       HSSFCell cell = row.createCell((short) 0);
+                       cell.setCellValue(444551234);
+                       HSSFCellStyle cellStyle = wb.createCellStyle();
+                       cellStyle.setDataFormat(format.getFormat("000-00-0000"));
+                       cell.setCellStyle(cellStyle);
+               }
+
+               { // formula cell
+                       row = sheet.createRow(6);
+                       HSSFCell cell = row.createCell((short) 0);
+                       cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
+                       cell.setCellFormula("SUM(12.25,12.25)/100");
+                       HSSFCellStyle cellStyle = wb.createCellStyle();
+                       cellStyle.setDataFormat(format.getFormat("##.00%;"));
+                       cell.setCellStyle(cellStyle);
+               }
        }
 
        /**
@@ -169,14 +169,14 @@ public class TestHSSFDataFormatter extends TestCase {
                // Valid date formats -- cell values should be date formatted & not "555.555"
                HSSFRow row = wb.getSheetAt(0).getRow(0);
                Iterator it = row.cellIterator();
-               System.out.println("==== VALID DATE FORMATS ====");
+               log("==== VALID DATE FORMATS ====");
                while (it.hasNext()) {
                        HSSFCell cell = (HSSFCell) it.next();
-                       System.out.println(formatter.formatCellValue(cell));
+                       log(formatter.formatCellValue(cell));
 
                        // should not be equal to "555.555"
                        assertTrue( ! "555.555".equals(formatter.formatCellValue(cell)));
-                       
+
                        // should contain "Jul" in the String
                        assertTrue( formatter.formatCellValue(cell).indexOf("Jul") > -1);
                }
@@ -184,70 +184,70 @@ public class TestHSSFDataFormatter extends TestCase {
                // test number formats
                row = wb.getSheetAt(0).getRow(1);
                it = row.cellIterator();
-               System.out.println("\n==== VALID NUMBER FORMATS ====");
+               log("\n==== VALID NUMBER FORMATS ====");
                while (it.hasNext()) {
                        HSSFCell cell = (HSSFCell) it.next();
-                       System.out.println(formatter.formatCellValue(cell));
-                       
+                       log(formatter.formatCellValue(cell));
+
                        // should not be equal to "1234567890.12345"
                        assertTrue( ! "1234567890.12345".equals(formatter.formatCellValue(cell)));
                }
-               
+
                // test bad number formats
                row = wb.getSheetAt(0).getRow(2);
                it = row.cellIterator();
-               System.out.println("\n==== INVALID NUMBER FORMATS ====");
+               log("\n==== INVALID NUMBER FORMATS ====");
                while (it.hasNext()) {
                        HSSFCell cell = (HSSFCell) it.next();
-                       System.out.println(formatter.formatCellValue(cell));
+                       log(formatter.formatCellValue(cell));
                        // should be equal to "1234567890.12345"
                        assertEquals("1234567890.12345", formatter.formatCellValue(cell));
                }
-               
+
                // test Zip+4 format
                row = wb.getSheetAt(0).getRow(3);
                HSSFCell cell = row.getCell(0);
-               System.out.println("\n==== ZIP FORMAT ====");
-               System.out.println(formatter.formatCellValue(cell));
+               log("\n==== ZIP FORMAT ====");
+               log(formatter.formatCellValue(cell));
                assertEquals("12345-6789", formatter.formatCellValue(cell));
-               
+
                // test phone number format
                row = wb.getSheetAt(0).getRow(4);
                cell = row.getCell(0);
-               System.out.println("\n==== PHONE FORMAT ====");
-               System.out.println(formatter.formatCellValue(cell));
+               log("\n==== PHONE FORMAT ====");
+               log(formatter.formatCellValue(cell));
                assertEquals("(555) 123-4567", formatter.formatCellValue(cell));
-               
+
                // test SSN format
                row = wb.getSheetAt(0).getRow(5);
                cell = row.getCell(0);
-               System.out.println("\n==== SSN FORMAT ====");
-               System.out.println(formatter.formatCellValue(cell));
-               assertEquals("444-55-1234", formatter.formatCellValue(cell));           
-               
+               log("\n==== SSN FORMAT ====");
+               log(formatter.formatCellValue(cell));
+               assertEquals("444-55-1234", formatter.formatCellValue(cell));
+
                // null test-- null cell should result in empty String
                assertEquals(formatter.formatCellValue(null), "");
-               
+
                // null test-- null cell should result in empty String
-               assertEquals(formatter.formatCellValue(null), "");              
-               
+               assertEquals(formatter.formatCellValue(null), "");
+
        }
 
        public void testGetFormattedCellValueHSSFCellHSSFFormulaEvaluator() {
                // test formula format
                HSSFRow row = wb.getSheetAt(0).getRow(6);
                HSSFCell cell = row.getCell(0);
-               System.out.println("\n==== FORMULA CELL ====");
-               
+               log("\n==== FORMULA CELL ====");
+
                // first without a formula evaluator
-               System.out.println(formatter.formatCellValue(cell) + "\t (without evaluator)");
-               assertEquals("SUM(12.25,12.25)/100", formatter.formatCellValue(cell));  
-               
-               // now with a formula evaluator         
+               log(formatter.formatCellValue(cell) + "\t (without evaluator)");
+               assertEquals("SUM(12.25,12.25)/100", formatter.formatCellValue(cell));
+
+               // now with a formula evaluator
                HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb);
                //! must set current row !
                evaluator.setCurrentRow(row);
-               System.out.println(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
+               log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
                assertEquals("24.50%", formatter.formatCellValue(cell,evaluator));
        }
 
@@ -259,24 +259,23 @@ public class TestHSSFDataFormatter extends TestCase {
         */
        public void testSetDefaultNumberFormat() {
                HSSFRow row = wb.getSheetAt(0).getRow(2);
-               Iterator it = row.cellIterator();       
+               Iterator it = row.cellIterator();
                Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD");
                formatter.setDefaultNumberFormat(defaultFormat);
                double value = 10d;
-               System.out.println("\n==== DEFAULT NUMBER FORMAT ====");
+               log("\n==== DEFAULT NUMBER FORMAT ====");
                while (it.hasNext()) {
-                       HSSFCell cell = (HSSFCell) it.next();           
+                       HSSFCell cell = (HSSFCell) it.next();
                        cell.setCellValue(cell.getNumericCellValue() * Math.random() / 1000000 - 1000);
-                       System.out.println(formatter.formatCellValue(cell));
+                       log(formatter.formatCellValue(cell));
                        assertTrue(formatter.formatCellValue(cell).startsWith("Balance "));
                        assertTrue(formatter.formatCellValue(cell).endsWith(" USD"));
-               }       
+               }
        }
 
-    public static void main(String [] args) {
-        System.out
-                .println("Testing org.apache.poi.hssf.usermodel.TestHSSFDataFormatter");
-        junit.textui.TestRunner.run(TestHSSFDataFormatter.class);
-    }  
-
+       private static void log(String msg) {
+               if (false) { // successful tests should be silent
+                       System.out.println(msg);
+               }
+       }
 }