]> source.dussan.org Git - poi.git/commitdiff
Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-63924...
authorNick Burch <nick@apache.org>
Tue, 9 Sep 2008 16:49:30 +0000 (16:49 +0000)
committerNick Burch <nick@apache.org>
Tue, 9 Sep 2008 16:49:30 +0000 (16:49 +0000)
https://svn.apache.org/repos/asf/poi/trunk

........
  r692918 | nick | 2008-09-07 19:32:51 +0100 (Sun, 07 Sep 2008) | 1 line

  Patch from bug #45738 - Initial HWPF support for Office Art Shapes
........
  r693085 | yegor | 2008-09-08 14:02:21 +0100 (Mon, 08 Sep 2008) | 1 line

  always call Workbook.cloneDrawings when cloning sheets
........
  r693175 | nick | 2008-09-08 18:43:31 +0100 (Mon, 08 Sep 2008) | 1 line

  Fix bug #45761 - Support for Very Hidden excel sheets in HSSF
........
  r693203 | josh | 2008-09-08 20:13:09 +0100 (Mon, 08 Sep 2008) | 1 line

  cosmetic fix for Area3DPtg.toString()
........
  r693221 | josh | 2008-09-08 20:49:03 +0100 (Mon, 08 Sep 2008) | 1 line

  Additional fix for 45720 - bug in HSSFWorkbook.findExistingBuiltinNameRecordIdx
........
  r693250 | josh | 2008-09-08 21:28:05 +0100 (Mon, 08 Sep 2008) | 1 line

  Fixes for DAY/MONTH/YEAR functions (junit cases added)
........
  r693289 | josh | 2008-09-08 22:34:45 +0100 (Mon, 08 Sep 2008) | 1 line

  Refactored OperandResolver coerce functions to convert BlankEval to 0.0
........
  r693309 | josh | 2008-09-08 23:46:41 +0100 (Mon, 08 Sep 2008) | 1 line

  Common refactoring for one arg numeric functions
........
  r693383 | yegor | 2008-09-09 07:58:35 +0100 (Tue, 09 Sep 2008) | 1 line

  don't increment the number of shapes when cloning a sheet with drawings
........

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@693510 13f79535-47bb-0310-9956-ffa450edef68

60 files changed:
src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/ddf/EscherContainerRecord.java
src/java/org/apache/poi/hssf/model/Workbook.java
src/java/org/apache/poi/hssf/record/BoundSheetRecord.java
src/java/org/apache/poi/hssf/record/NameRecord.java
src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java
src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java
src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java
src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java
src/java/org/apache/poi/hssf/record/formula/eval/TwoOperandNumericOperation.java
src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java
src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java
src/java/org/apache/poi/hssf/record/formula/functions/Abs.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Acos.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Asin.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Asinh.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Atan.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Atanh.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Cos.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Cosh.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Day.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Even.java
src/java/org/apache/poi/hssf/record/formula/functions/Exp.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Fact.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Int.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Ln.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Log10.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java
src/java/org/apache/poi/hssf/record/formula/functions/Mid.java
src/java/org/apache/poi/hssf/record/formula/functions/Month.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/NumericFunctionOneArg.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/formula/functions/Odd.java
src/java/org/apache/poi/hssf/record/formula/functions/Radians.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Sign.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Sin.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Tan.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java [deleted file]
src/java/org/apache/poi/hssf/record/formula/functions/Year.java [deleted file]
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/data/45761.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls
src/testcases/org/apache/poi/hssf/data/externalFunctionExample.xls
src/testcases/org/apache/poi/hssf/data/testRRaC.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java
src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java

index a78c832e5af0407028abfe152ecaf94ba2696dc2..c1152ef3440df6c3481abd4ac0bc7b083ffb5493 100644 (file)
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1.1-alpha1" date="2008-??-??">
-           <action dev="POI-DEVELOPERS" type="fix">45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings</action>
-           <action dev="POI-DEVELOPERS" type="fix">45728 Fix for SlideShow.reorderSlide in HSLF</action>
+           <action dev="POI-DEVELOPERS" type="add">45761 - Support for Very Hidden excel sheets in HSSF</action>
+           <action dev="POI-DEVELOPERS" type="add">45738 - Initial HWPF support for Office Art Shapes</action>
+           <action dev="POI-DEVELOPERS" type="fix">45720 - Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings</action>
+           <action dev="POI-DEVELOPERS" type="fix">45728 - Fix for SlideShow.reorderSlide in HSLF</action>
            <action dev="POI-DEVELOPERS" type="add">Initial support for embedded movies and controls in HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF()</action>
            <action dev="POI-DEVELOPERS" type="add">Support for HPBF Publisher hyperlinks, including during text extraction</action>
index 85bda8b74fe3a82208183d521bc41559b34880e5..155d522d7b9037a4a18a9a20e9518a89b147c223 100644 (file)
            <action dev="POI-DEVELOPERS" type="add">Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx</action>
         </release>
         <release version="3.1.1-alpha1" date="2008-??-??">
-           <action dev="POI-DEVELOPERS" type="fix">45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings</action>
-           <action dev="POI-DEVELOPERS" type="fix">45728 Fix for SlideShow.reorderSlide in HSLF</action>
+           <action dev="POI-DEVELOPERS" type="add">45761 - Support for Very Hidden excel sheets in HSSF</action>
+           <action dev="POI-DEVELOPERS" type="add">45738 - Initial HWPF support for Office Art Shapes</action>
+           <action dev="POI-DEVELOPERS" type="fix">45720 - Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings</action>
+           <action dev="POI-DEVELOPERS" type="fix">45728 - Fix for SlideShow.reorderSlide in HSLF</action>
            <action dev="POI-DEVELOPERS" type="add">Initial support for embedded movies and controls in HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF()</action>
            <action dev="POI-DEVELOPERS" type="add">Support for HPBF Publisher hyperlinks, including during text extraction</action>
index bb188d5387be8dc16b32b2e6c3a5f052b1f0315f..9c204226e440b6dc8d506eac92947ef0316e8e9e 100644 (file)
@@ -243,10 +243,11 @@ public class EscherContainerRecord extends EscherRecord
     public void getRecordsById(short recordId, List out){
         for(Iterator it = childRecords.iterator(); it.hasNext();) {
             Object er = it.next();
-            if(er instanceof EscherContainerRecord) {
-                EscherContainerRecord c = (EscherContainerRecord)er;
+            EscherRecord r = (EscherRecord)er;
+            if(r instanceof EscherContainerRecord) {
+                EscherContainerRecord c = (EscherContainerRecord)r;
                 c.getRecordsById(recordId, out );
-            } else if (er instanceof EscherSpRecord){
+            } else if (r.getRecordId() == recordId){
                 out.add(er);
             }
         }
index f093feef663e5bb7427194a4eb35f29cbfcf7b40..7976588d3495081d28076b214a4a5e2b1fa6b757 100644 (file)
@@ -560,32 +560,72 @@ public final class Workbook implements Model {
     }
 
     /**
-     * gets the hidden flag for a given sheet.
+     * Gets the hidden flag for a given sheet.
+     * Note that a sheet could instead be 
+     *  set to be very hidden, which is different
+     *  ({@link #isSheetVeryHidden(int)})
      *
      * @param sheetnum the sheet number (0 based)
      * @return True if sheet is hidden
      */
-
     public boolean isSheetHidden(int sheetnum) {
         return getBoundSheetRec(sheetnum).isHidden();
     }
 
+    /**
+     * Gets the very hidden flag for a given sheet.
+     * This is different from the normal 
+     *  hidden flag 
+     *  ({@link #isSheetHidden(int)})
+     *
+     * @param sheetnum the sheet number (0 based)
+     * @return True if sheet is very hidden
+     */
+    public boolean isSheetVeryHidden(int sheetnum) {
+        return getBoundSheetRec(sheetnum).isVeryHidden();
+    }
+
     /**
      * Hide or unhide a sheet
      * 
      * @param sheetnum The sheet number
      * @param hidden True to mark the sheet as hidden, false otherwise
      */
-    
     public void setSheetHidden(int sheetnum, boolean hidden) {
         getBoundSheetRec(sheetnum).setHidden(hidden);
     }
+    
+    /**
+     * Hide or unhide a sheet.
+     *  0 = not hidden
+     *  1 = hidden
+     *  2 = very hidden.
+     * 
+     * @param sheetnum The sheet number
+     * @param hidden 0 for not hidden, 1 for hidden, 2 for very hidden
+     */
+    public void setSheetHidden(int sheetnum, int hidden) {
+       BoundSheetRecord bsr = getBoundSheetRec(sheetnum);
+       boolean h = false;
+       boolean vh = false;
+       if(hidden == 0) {
+       } else if(hidden == 1) {
+               h = true;
+       } else if(hidden == 2) {
+               vh = true;
+       } else {
+               throw new IllegalArgumentException("Invalid hidden flag " + hidden + " given, must be 0, 1 or 2");
+       }
+       bsr.setHidden(h);
+       bsr.setVeryHidden(vh);
+    }
+    
+    
     /**
      * get the sheet's index
      * @param name  sheet name
      * @return sheet index or -1 if it was not found.
      */
-
     public int getSheetIndex(String name) {
         int retval = -1;
 
@@ -2426,6 +2466,10 @@ public final class Workbook implements Model {
         int aggLoc = sheet.aggregateDrawingRecords(drawingManager, false);
         if(aggLoc != -1) {
             EscherAggregate agg = (EscherAggregate) sheet.findFirstRecordBySid(EscherAggregate.sid);
+            EscherContainerRecord escherContainer = agg.getEscherContainer();
+            if (escherContainer == null) {
+                return;
+            }
 
             EscherDggRecord dgg = drawingManager.getDgg();
 
@@ -2435,7 +2479,7 @@ public final class Workbook implements Model {
             dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
 
             EscherDgRecord dg = null;
-            for(Iterator it = agg.getEscherContainer().getChildRecords().iterator(); it.hasNext();) {
+            for(Iterator it = escherContainer.getChildRecords().iterator(); it.hasNext();) {
                 Object er = it.next();
                 if(er instanceof EscherDgRecord) {
                     dg = (EscherDgRecord)er;
@@ -2449,6 +2493,8 @@ public final class Workbook implements Model {
                     for(Iterator spIt = spRecords.iterator(); spIt.hasNext();) {
                         EscherSpRecord sp = (EscherSpRecord)spIt.next();
                         int shapeId = drawingManager.allocateShapeId((short)dgId, dg);
+                        //allocateShapeId increments the number of shapes. roll back to the previous value
+                        dg.setNumShapes(dg.getNumShapes()-1);
                         sp.setShapeId(shapeId);
                     }
                 }
index 2ef4c67d2c251920303aafafe09c9d294ad704ab..1f7106ad7299d441e5d367c3132e2ac00fd0cb85 100644 (file)
@@ -36,6 +36,7 @@ public final class BoundSheetRecord extends Record {
     public final static short sid = 0x0085;
 
        private static final BitField hiddenFlag = BitFieldFactory.getInstance(0x01);
+       private static final BitField veryHiddenFlag = BitFieldFactory.getInstance(0x02);
     private int field_1_position_of_BOF;
     private short field_2_option_flags;
     private byte field_3_sheetname_length;
@@ -301,11 +302,31 @@ public final class BoundSheetRecord extends Record {
         return sid;
     }
 
+    /**
+     * Is the sheet hidden? Different from very hidden 
+     */
     public boolean isHidden() {
            return hiddenFlag.isSet(field_2_option_flags);
     }
 
+    /**
+     * Is the sheet hidden? Different from very hidden 
+     */
     public void setHidden(boolean hidden) {
            field_2_option_flags = hiddenFlag.setShortBoolean(field_2_option_flags, hidden);
     }
+
+    /**
+     * Is the sheet very hidden? Different from (normal) hidden 
+     */
+    public boolean isVeryHidden() {
+           return veryHiddenFlag.isSet(field_2_option_flags);
+    }
+
+    /**
+     * Is the sheet very hidden? Different from (normal) hidden 
+     */
+    public void setVeryHidden(boolean veryHidden) {
+           field_2_option_flags = veryHiddenFlag.setShortBoolean(field_2_option_flags, veryHidden);
+    }
 }
index 77296becd8529942eb288bb19b4c872d3c34aecd..0716c448d85959a6c269a30937f7b99218962cc5 100644 (file)
@@ -82,8 +82,9 @@ public final class NameRecord extends Record {
 
        private short             field_1_option_flag;
        private byte              field_2_keyboard_shortcut;
-       private short             field_5_index_to_sheet;     // unused: see field_6
-       /** the one based sheet number.  Zero if this is a global name */
+       /** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name  */
+       private short             field_5_externSheetIndex_plus1;
+       /** the one based sheet number.  */
        private int               field_6_sheetNumber;
        private boolean           field_11_nameIsMultibyte;
        private byte              field_12_built_in_code;
@@ -144,7 +145,7 @@ public final class NameRecord extends Record {
 
        /**
         * For named ranges, and built-in names
-        * @return the 1-based sheet number.  Zero if this is a global name
+        * @return the 1-based sheet number. 
         */
        public int getSheetNumber()
        {
@@ -384,7 +385,7 @@ public final class NameRecord extends Record {
                LittleEndian.putByte(data, 7 + offset, getNameTextLength());
                // Note -
                LittleEndian.putUShort(data, 8 + offset, Ptg.getEncodedSizeWithoutArrayData(field_13_name_definition));
-               LittleEndian.putUShort(data, 10 + offset, field_5_index_to_sheet);
+               LittleEndian.putUShort(data, 10 + offset, field_5_externSheetIndex_plus1);
                LittleEndian.putUShort(data, 12 + offset, field_6_sheetNumber);
                LittleEndian.putByte(data, 14 + offset, field_7_length_custom_menu);
                LittleEndian.putByte(data, 15 + offset, field_8_length_description_text);
@@ -557,7 +558,7 @@ public final class NameRecord extends Record {
                field_2_keyboard_shortcut           = in.readByte();
                int field_3_length_name_text        = in.readByte();
                int field_4_length_name_definition  = in.readShort();
-               field_5_index_to_sheet              = in.readShort();
+               field_5_externSheetIndex_plus1      = in.readShort();
                field_6_sheetNumber                 = in.readUShort();
                int field_7_length_custom_menu      = in.readUByte();
                int field_8_length_description_text = in.readUByte();
@@ -649,8 +650,8 @@ public final class NameRecord extends Record {
                sb.append("    .option flags           = ").append(HexDump.shortToHex(field_1_option_flag)).append("\n");
                sb.append("    .keyboard shortcut      = ").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n");
                sb.append("    .length of the name     = ").append(getNameTextLength()).append("\n");
-               sb.append("    .unused                 = ").append( field_5_index_to_sheet ).append("\n");
-               sb.append("    .index to sheet (1-based, 0=Global) = ").append( field_6_sheetNumber ).append("\n");
+               sb.append("    .extSheetIx(1-based, 0=Global)= ").append( field_5_externSheetIndex_plus1 ).append("\n");
+               sb.append("    .sheetTabIx             = ").append(field_6_sheetNumber ).append("\n");
                sb.append("    .Menu text length       = ").append(field_14_custom_menu_text.length()).append("\n");
                sb.append("    .Description text length= ").append(field_15_description_text.length()).append("\n");
                sb.append("    .Help topic text length = ").append(field_16_help_topic_text.length()).append("\n");
index ba207ab5c60843a7ce1c463d86ced0324aec5c4e..8848cb603b7aa8664c699ad28a02c849a5c4534a 100644 (file)
@@ -59,6 +59,7 @@ public final class Area3DPtg extends AreaPtgBase {
        public String toString() {
                StringBuffer sb = new StringBuffer();
                sb.append(getClass().getName());
+               sb.append(" [");
                sb.append("sheetIx=").append(getExternSheetIndex());
                sb.append(" ! ");
                sb.append(formatReferenceAsString());
index 9dd6d09819b4f0b956dbb5e246cca604a2fb4acf..71cfa03591e2d086f5a6888d090f0108e9a6373a 100644 (file)
@@ -61,9 +61,6 @@ final class ParityFunction implements FreeRefFunction {
        private static int evaluateArgParity(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
                ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
                
-               if (ve == BlankEval.INSTANCE) {
-                       return 0;
-               }
                double d = OperandResolver.coerceValueToDouble(ve);
                if (d < 0) {
                        d = -d;
index 96718ef4ecd717934c9930e0c611f4945797caea..f5bc3fe8f41d0e167c28e03d03b6047546cc3053 100644 (file)
@@ -97,9 +97,6 @@ final class YearFrac implements FreeRefFunction {
                        Calendar date = parseDate(strVal);
                        return DateUtil.getExcelDate(date, false);
                }
-               if (ve instanceof BlankEval) {
-                       return 0.0;
-               }
                return OperandResolver.coerceValueToDouble(ve);
        }
 
index fe58c69c095013fee76cecc18b9fa4c9b4c932ca..a1c7356fa90984d98422aa9783cf6823e9455b16 100644 (file)
@@ -90,20 +90,20 @@ public abstract class FunctionEval implements OperationEval {
         retval[10] = new Na(); // NA
         retval[11] = new Npv(); // NPV
         retval[12] = new Stdev(); // STDEV
-        retval[13] = new Dollar(); // DOLLAR
+        retval[13] = NumericFunctionOneArg.DOLLAR;
         retval[14] = new Fixed(); // FIXED
-        retval[15] = new Sin(); // SIN
-        retval[16] = new Cos(); // COS
-        retval[17] = new Tan(); // TAN
-        retval[18] = new Atan(); // ATAN
+        retval[15] = NumericFunctionOneArg.SIN;
+        retval[16] = NumericFunctionOneArg.COS;
+        retval[17] = NumericFunctionOneArg.TAN;
+        retval[18] = NumericFunctionOneArg.ATAN;
         retval[19] = new Pi(); // PI
-        retval[20] = new Sqrt(); // SQRT
-        retval[21] = new Exp(); // EXP
-        retval[22] = new Ln(); // LN
-        retval[23] = new Log10(); // LOG10
-        retval[24] = new Abs(); // ABS
-        retval[25] = new Int(); // INT
-        retval[26] = new Sign(); // SIGN
+        retval[20] = NumericFunctionOneArg.SQRT;
+        retval[21] = NumericFunctionOneArg.EXP;
+        retval[22] = NumericFunctionOneArg.LN;
+        retval[23] = NumericFunctionOneArg.LOG10;
+        retval[24] = NumericFunctionOneArg.ABS;
+        retval[25] = NumericFunctionOneArg.INT;
+        retval[26] = NumericFunctionOneArg.SIGN;
         retval[27] = new Round(); // ROUND
         retval[28] = new Lookup(); // LOOKUP
         retval[29] = new Index(); // INDEX
@@ -143,9 +143,9 @@ public abstract class FunctionEval implements OperationEval {
         retval[64] = new Match(); // MATCH
         retval[65] = new Date(); // DATE
         retval[66] = new Time(); // TIME
-        retval[67] = new Day(); // DAY
-        retval[68] = new Month(); // MONTH
-        retval[69] = new Year(); // YEAR
+        retval[67] = CalendarFieldFunction.DAY; // DAY
+        retval[68] = CalendarFieldFunction.MONTH; // MONTH
+        retval[69] = CalendarFieldFunction.YEAR; // YEAR
         retval[70] = new Weekday(); // WEEKDAY
         retval[71] = new Hour(); // HOUR
         retval[72] = new Minute(); // MINUTE
@@ -174,8 +174,8 @@ public abstract class FunctionEval implements OperationEval {
         retval[95] = new NotImplementedFunction(); // SELECTION
         retval[96] = new Result(); // RESULT
         retval[97] = new Atan2(); // ATAN2
-        retval[98] = new Asin(); // ASIN
-        retval[99] = new Acos(); // ACOS
+        retval[98] = NumericFunctionOneArg.ASIN;
+        retval[99] = NumericFunctionOneArg.ACOS;
         retval[100] = new Choose(); // CHOOSE
         retval[101] = new Hlookup(); // HLOOKUP
         retval[102] = new Vlookup(); // VLOOKUP
@@ -256,7 +256,7 @@ public abstract class FunctionEval implements OperationEval {
         retval[181] = new Help(); // HELP
         retval[182] = new NotImplementedFunction(); // GETBAR
         retval[183] = new Product(); // PRODUCT
-        retval[184] = new Fact(); // FACT
+        retval[184] = NumericFunctionOneArg.FACT;
         retval[185] = new NotImplementedFunction(); // GETCELL
         retval[186] = new NotImplementedFunction(); // GETWORKSPACE
         retval[187] = new NotImplementedFunction(); // GETWINDOW
@@ -293,12 +293,12 @@ public abstract class FunctionEval implements OperationEval {
         retval[222] = new Vdb(); // VDB
         retval[227] = new Median(); // MEDIAN
         retval[228] = new Sumproduct(); // SUMPRODUCT
-        retval[229] = new Sinh(); // SINH
-        retval[230] = new Cosh(); // COSH
-        retval[231] = new Tanh(); // TANH
-        retval[232] = new Asinh(); // ASINH
-        retval[233] = new Acosh(); // ACOSH
-        retval[234] = new Atanh(); // ATANH
+        retval[229] = NumericFunctionOneArg.SINH;
+        retval[230] = NumericFunctionOneArg.COSH;
+        retval[231] = NumericFunctionOneArg.TANH;
+        retval[232] = NumericFunctionOneArg.ASINH;
+        retval[233] = NumericFunctionOneArg.ACOSH;
+        retval[234] = NumericFunctionOneArg.ATANH;
         retval[235] = new Dget(); // DGET
         retval[236] = new NotImplementedFunction(); // CREATEOBJECT
         retval[237] = new Volatile(); // VOLATILE
@@ -403,8 +403,8 @@ public abstract class FunctionEval implements OperationEval {
         retval[339] = new NotImplementedFunction(); // GETPIVOTTABLE
         retval[340] = new NotImplementedFunction(); // GETPIVOTFIELD
         retval[341] = new NotImplementedFunction(); // GETPIVOTITEM
-        retval[342] = new Radians(); // RADIANS
-        retval[343] = new Degrees(); // DEGREES
+        retval[342] = NumericFunctionOneArg.RADIANS;
+        retval[343] = NumericFunctionOneArg.DEGREES;
         retval[344] = new Subtotal(); // SUBTOTAL
         retval[345] = new Sumif(); // SUMIF
         retval[346] = new Countif(); // COUNTIF
index 627b26998950850e3fd38eeb3e3b460a8300a793..87f45236bfac4a5086ff7206e55962c92842091f 100755 (executable)
@@ -171,7 +171,8 @@ public final class OperandResolver {
 
        /**
         * Applies some conversion rules if the supplied value is not already an integer.<br/>
-        * Value is first coerced to a <tt>double</tt> ( See <tt>coerceValueToDouble()</tt> ).<p/>
+        * Value is first coerced to a <tt>double</tt> ( See <tt>coerceValueToDouble()</tt> ).
+        * Note - <tt>BlankEval</tt> is converted to <code>0</code>.<p/> 
         * 
         * Excel typically converts doubles to integers by truncating toward negative infinity.<br/>
         * The equivalent java code is:<br/>
@@ -181,6 +182,9 @@ public final class OperandResolver {
         * 
         */
        public static int coerceValueToInt(ValueEval ev) throws EvaluationException {
+               if (ev == BlankEval.INSTANCE) {
+                       return 0;
+               }
                double d = coerceValueToDouble(ev);
                // Note - the standard java type conversion from double to int truncates toward zero.
                // but Math.floor() truncates toward negative infinity
@@ -189,16 +193,20 @@ public final class OperandResolver {
 
        /**
         * Applies some conversion rules if the supplied value is not already a number.
-        * Note - <tt>BlankEval</tt> is not supported and must be handled by the caller. 
-        * @param ev must be a <tt>NumberEval</tt>, <tt>StringEval</tt> or <tt>BoolEval</tt>
+        * Note - <tt>BlankEval</tt> is converted to {@link NumberEval#ZERO}. 
+        * @param ev must be a {@link NumberEval}, {@link StringEval}, {@link BoolEval} or 
+        * {@link BlankEval}
         * @return actual, parsed or interpreted double value (respectively).
         * @throws EvaluationException(#VALUE!) only if a StringEval is supplied and cannot be parsed
         * as a double (See <tt>parseDouble()</tt> for allowable formats).
-        * @throws RuntimeException if the supplied parameter is not <tt>NumberEval</tt>,
-        *  <tt>StringEval</tt> or <tt>BoolEval</tt>
+        * @throws RuntimeException if the supplied parameter is not {@link NumberEval}, 
+        * {@link StringEval}, {@link BoolEval} or {@link BlankEval}
         */
        public static double coerceValueToDouble(ValueEval ev) throws EvaluationException {
 
+               if (ev == BlankEval.INSTANCE) {
+                       return 0.0;
+               }
                if (ev instanceof NumericValueEval) {
                        // this also handles booleans
                        return ((NumericValueEval)ev).getNumberValue();
index d03e4474521a08753ae02bc8df58dc6228ae1c5f..d8a579c42dcbad32deaa6caba6f2a0c891f304a1 100755 (executable)
@@ -33,12 +33,9 @@ public final class PercentEval implements OperationEval {
                if (args.length != 1) {
                        return ErrorEval.VALUE_INVALID;
                }
-       double d0;
+               double d0;
                try {
                        ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol);
-                       if (ve instanceof BlankEval) {
-                               return NumberEval.ZERO;
-                       }
                        d0 = OperandResolver.coerceValueToDouble(ve);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
@@ -50,7 +47,7 @@ public final class PercentEval implements OperationEval {
                return 1;
        }
        public final int getType() {
-       // TODO - remove
-        throw new RuntimeException("obsolete code should not be called");
-    }
+               // TODO - remove
+               throw new RuntimeException("obsolete code should not be called");
+       }
 }
index 665ba4b4601b251f313eae812448b353e197ffe0..0f2933faea074fc7638bbca72d0e7891bd25fc70 100644 (file)
@@ -23,18 +23,15 @@ package org.apache.poi.hssf.record.formula.eval;
 abstract class TwoOperandNumericOperation implements OperationEval {
 
        public final int getType() {
-       // TODO - remove
-        throw new RuntimeException("obsolete code should not be called");
-    }
-    protected final double singleOperandEvaluate(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
-       ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
-               if (ve instanceof BlankEval) {
-                       return 0.0;
-               }
-               return OperandResolver.coerceValueToDouble(ve);
-    }
-    
-    public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+               // TODO - remove
+               throw new RuntimeException("obsolete code should not be called");
+       }
+       protected final double singleOperandEvaluate(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
+               ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+               return OperandResolver.coerceValueToDouble(ve);
+       }
+       
+       public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
                double result;
                try {
                        double d0 = singleOperandEvaluate(args[0], srcCellRow, srcCellCol);
@@ -46,8 +43,8 @@ abstract class TwoOperandNumericOperation implements OperationEval {
                } catch (EvaluationException e) {
                        return e.getErrorEval();
                }
-       return new NumberEval(result);
-    }
+               return new NumberEval(result);
+       }
        protected abstract double evaluate(double d0, double d1) throws EvaluationException;
        public final int getNumberOfOperands() {
                return 2;
index 8174429e01b2745684bdc778868c8a7a09e767bb..780334ae8d1cc5b24eecbbfd17e6876f56d83873 100644 (file)
@@ -33,12 +33,9 @@ public final class UnaryMinusEval implements OperationEval {
                if (args.length != 1) {
                        return ErrorEval.VALUE_INVALID;
                }
-       double d;
+               double d;
                try {
                        ValueEval ve = OperandResolver.getSingleValue(args[0], srcRow, srcCol);
-                       if (ve instanceof BlankEval) {
-                               return NumberEval.ZERO;
-                       }
                        d = OperandResolver.coerceValueToDouble(ve);
                } catch (EvaluationException e) {
                        return e.getErrorEval();
@@ -50,7 +47,7 @@ public final class UnaryMinusEval implements OperationEval {
                return 1;
        }
        public final int getType() {
-       // TODO - remove
-        throw new RuntimeException("obsolete code should not be called");
-    }
+               // TODO - remove
+               throw new RuntimeException("obsolete code should not be called");
+       }
 }
index 66c5f6801713abf4fada69572cf97b8db5668d97..831d342866d2c74f45066ede088d9bab1e13cfde 100644 (file)
@@ -24,21 +24,18 @@ package org.apache.poi.hssf.record.formula.eval;
  */
 public final class UnaryPlusEval implements OperationEval {
 
-    public static final OperationEval instance = new UnaryPlusEval();
-    
-    private UnaryPlusEval() {
-    }
+       public static final OperationEval instance = new UnaryPlusEval();
+       
+       private UnaryPlusEval() {
+       }
 
-    public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
-       if(args.length != 1) {
-               return ErrorEval.VALUE_INVALID;
-       }
-       double d;
+       public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+               if(args.length != 1) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+               double d;
                try {
                        ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
-                       if(ve instanceof BlankEval) {
-                               return NumberEval.ZERO;
-                       }
                        if(ve instanceof StringEval) {
                                // Note - asymmetric with UnaryMinus
                                // -"hello" evaluates to #VALUE!
@@ -49,14 +46,14 @@ public final class UnaryPlusEval implements OperationEval {
                } catch (EvaluationException e) {
                        return e.getErrorEval();
                }
-       return new NumberEval(+d);      
-    }
+               return new NumberEval(+d);
+       }
 
-    public int getNumberOfOperands() {
-        return 1;
-    }
+       public int getNumberOfOperands() {
+               return 1;
+       }
 
-    public int getType() {
-        throw new RuntimeException("obsolete code should not be called");
-    }
+       public int getType() {
+               throw new RuntimeException("obsolete code should not be called");
+       }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Abs.java b/src/java/org/apache/poi/hssf/record/formula/functions/Abs.java
deleted file mode 100644 (file)
index 1bebb35..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *  
- */
-public class Abs extends NumericFunction {
-    
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        
-        if (retval == null) {
-            d = Math.abs(d);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.VALUE_INVALID
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Acos.java b/src/java/org/apache/poi/hssf/record/formula/functions/Acos.java
deleted file mode 100644 (file)
index bc5b572..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Acos extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.acos(d);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java
deleted file mode 100644 (file)
index 794516e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- * Support for hyperbolic trig functions was added as a part of
- * Java distribution only in JDK1.5. This class uses custom
- * naive implementation based on formulas at:
- * http://www.math2.org/math/trig/hyperbolics.htm
- * These formulas seem to agree with excel's implementation.
- *
- */
-public class Acosh extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-        }
-
-        if (retval == null) {
-            d = MathX.acosh(d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Asin.java b/src/java/org/apache/poi/hssf/record/formula/functions/Asin.java
deleted file mode 100644 (file)
index 868ff7a..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Asin extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.asin(d);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Asinh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Asinh.java
deleted file mode 100644 (file)
index 8814dc3..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- * Support for hyperbolic trig functions was added as a part of
- * Java distribution only in JDK1.5. This class uses custom
- * naive implementation based on formulas at:
- * http://www.math2.org/math/trig/hyperbolics.htm
- * These formulas seem to agree with excel's implementation.
- *
- */
-public class Asinh extends NumericFunction {
-
-    
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = MathX.asinh(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Atan.java b/src/java/org/apache/poi/hssf/record/formula/functions/Atan.java
deleted file mode 100644 (file)
index 8266ad2..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Atan extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.atan(d);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Atanh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Atanh.java
deleted file mode 100644 (file)
index d472b1f..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- * Support for hyperbolic trig functions was added as a part of
- * Java distribution only in JDK1.5. This class uses custom
- * naive implementation based on formulas at:
- * http://www.math2.org/math/trig/hyperbolics.htm
- * These formulas seem to agree with excel's implementation.
- *
- */
-public class Atanh extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = MathX.atanh(d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java
new file mode 100644 (file)
index 0000000..b1ea02f
--- /dev/null
@@ -0,0 +1,92 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.record.formula.functions;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+
+/**
+ * Implementation of Excel functions DAY, MONTH and YEAR
+ * 
+ * 
+ * @author Guenter Kickinger g.kickinger@gmx.net
+ */
+public final class CalendarFieldFunction implements Function {
+       
+       public static final Function YEAR = new CalendarFieldFunction(Calendar.YEAR, false);
+       public static final Function MONTH = new CalendarFieldFunction(Calendar.MONTH, true);
+       public static final Function DAY = new CalendarFieldFunction(Calendar.DAY_OF_MONTH, false);
+       
+       private final int _dateFieldId;
+       private final boolean _needsOneBaseAdjustment;
+
+       private CalendarFieldFunction(int dateFieldId, boolean needsOneBaseAdjustment) {
+               _dateFieldId = dateFieldId;
+               _needsOneBaseAdjustment = needsOneBaseAdjustment;
+       }
+
+       public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
+               if (operands.length != 1) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+
+               int val;
+               try {
+                       ValueEval ve = OperandResolver.getSingleValue(operands[0], srcCellRow, srcCellCol);
+                       val = OperandResolver.coerceValueToInt(ve);
+               } catch (EvaluationException e) {
+                       return e.getErrorEval();
+               }
+               if (val < 0) {
+                       return ErrorEval.NUM_ERROR;
+               }
+               return new NumberEval(getCalField(val));
+       }
+
+       private int getCalField(int serialDay) {
+               if (serialDay == 0) {
+                       // Special weird case
+                       // day zero should be 31-Dec-1899,  but Excel seems to think it is 0-Jan-1900
+                       switch (_dateFieldId) {
+                               case Calendar.YEAR: return 1900;
+                               case Calendar.MONTH: return 1;
+                               case Calendar.DAY_OF_MONTH: return 0;
+                       }
+                       throw new IllegalStateException("bad date field " + _dateFieldId);
+               }
+               Date d = HSSFDateUtil.getJavaDate(serialDay, false); // TODO fix 1900/1904 problem
+
+               Calendar c = new GregorianCalendar();
+               c.setTime(d);
+
+               int result = c.get(_dateFieldId);
+               if (_needsOneBaseAdjustment) {
+                       result++;
+               }
+               return result;
+       }
+}
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Cos.java b/src/java/org/apache/poi/hssf/record/formula/functions/Cos.java
deleted file mode 100644 (file)
index f262797..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Cos extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.cos(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Cosh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Cosh.java
deleted file mode 100644 (file)
index 41c8650..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Cosh extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = MathX.cosh(d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Day.java b/src/java/org/apache/poi/hssf/record/formula/functions/Day.java
deleted file mode 100644 (file)
index 0ae5694..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.record.formula.functions;
-
-import org.apache.poi.hssf.usermodel.HSSFDateUtil;
-
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-
-/**
- * @author Pavel Krupets
- */
-public class Day extends NumericFunction {
-    /**
-     * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
-     */
-    public Eval evaluate(Eval[] operands, int srcCellRow, short
-srcCellCol) {
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0],
-srcCellRow, srcCellCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
-                    java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
-                    java.util.Calendar c = java.util.Calendar.getInstance();
-                    c.setTime(d);
-                    retval = new NumberEval(c.get(java.util.Calendar.DAY_OF_MONTH));
-                } else {
-                    retval = ErrorEval.NUM_ERROR;
-                }
-            } else if (ve instanceof BlankEval) {
-                // do nothing
-            } else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        return retval;
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java b/src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java
deleted file mode 100644 (file)
index e85e14d..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *  
- */
-public class Degrees extends NumericFunction {
-    
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        
-        if (retval == null) {
-            d = Math.toDegrees(d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java
deleted file mode 100644 (file)
index a65f65a..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Dollar extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
index 9149671676f0f7074f7597ad730d931aafc4542d..272863908c0a5d20b47c185d51c2a08516b6c81d 100644 (file)
@@ -1,73 +1,49 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *  
  */
-public class Even extends NumericFunction {
+public final class Even extends NumericFunctionOneArg {
+
+       private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
 
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        
-        if (retval == null) {
-            if (!Double.isNaN(d) && !Double.isInfinite(d)) {
-                d = (d==0) 
-                    ? 0 
-                    : (((long) (d/2))*2 == d)
-                        ? d
-                        : (d < 0) 
-                            ? ((((long) (d/2))<<1)-2) 
-                            : ((((long) (d/2))<<1)+2);
-            }
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
+       protected double evaluate(double d) {
+               if (d==0) {
+                       return 0;
+               }
+               long result;
+               if (d>0) {
+                       result = calcEven(d);
+               } else {
+                       result = -calcEven(-d);
+               }
+               return result;
+       }
 
+       private static long calcEven(double d) {
+               long x = ((long) d) & PARITY_MASK;
+               if (x == d) {
+                       return x;
+               }
+               return x + 2;
+       }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Exp.java b/src/java/org/apache/poi/hssf/record/formula/functions/Exp.java
deleted file mode 100644 (file)
index d0b122a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Exp extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.pow(E, d);
-            retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fact.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fact.java
deleted file mode 100644 (file)
index 128b167..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 22, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Fact extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            if (d < Integer.MAX_VALUE && d >= 0) {
-                d = MathX.factorial((int) d);
-                retval = (Double.isNaN(d))
-                ? (ValueEval) ErrorEval.VALUE_INVALID
-                : (Double.isInfinite(d))
-                        ? (ValueEval) ErrorEval.NUM_ERROR
-                        : new NumberEval(d);
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Int.java b/src/java/org/apache/poi/hssf/record/formula/functions/Int.java
deleted file mode 100644 (file)
index 5b26a8a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Int extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            if (d < 0) {
-                d = Math.round(d-0.5);
-            }
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval((long) d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ln.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ln.java
deleted file mode 100644 (file)
index 95392a4..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Ln extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.log(d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Log10.java b/src/java/org/apache/poi/hssf/record/formula/functions/Log10.java
deleted file mode 100644 (file)
index cf8b9bd..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Log10 extends NumericFunction {
-    private static final double LOG_10_TO_BASE_e = Math.log(10);
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.log(d) / LOG_10_TO_BASE_e;
-            retval = (Double.isNaN(d) || Double.isInfinite(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
index ee67ef8ec59bfe69e5dda72caeb74cf0b046b7a2..613a3d144cb8cdb843ad2129213b9e05119a4748 100644 (file)
@@ -339,23 +339,19 @@ final class LookupUtils {
                        throw EvaluationException.invalidRef();
                }
                int oneBasedIndex;
-               if(veRowColIndexArg instanceof BlankEval) {
-                       oneBasedIndex = 0;
-               } else {
-                       if(veRowColIndexArg instanceof StringEval) {
-                               StringEval se = (StringEval) veRowColIndexArg;
-                               String strVal = se.getStringValue();
-                               Double dVal = OperandResolver.parseDouble(strVal);
-                               if(dVal == null) {
-                                       // String does not resolve to a number. Raise #REF! error.
-                                       throw EvaluationException.invalidRef();
-                                       // This includes text booleans "TRUE" and "FALSE".  They are not valid.
-                               }
-                               // else - numeric value parses OK
+               if(veRowColIndexArg instanceof StringEval) {
+                       StringEval se = (StringEval) veRowColIndexArg;
+                       String strVal = se.getStringValue();
+                       Double dVal = OperandResolver.parseDouble(strVal);
+                       if(dVal == null) {
+                               // String does not resolve to a number. Raise #REF! error.
+                               throw EvaluationException.invalidRef();
+                               // This includes text booleans "TRUE" and "FALSE".  They are not valid.
                        }
-                       // actual BoolEval values get interpreted as FALSE->0 and TRUE->1
-                       oneBasedIndex = OperandResolver.coerceValueToInt(veRowColIndexArg);
+                       // else - numeric value parses OK
                }
+               // actual BoolEval values get interpreted as FALSE->0 and TRUE->1
+               oneBasedIndex = OperandResolver.coerceValueToInt(veRowColIndexArg);
                if (oneBasedIndex < 1) {
                        // note this is asymmetric with the errors when the index is too large (#REF!)  
                        throw EvaluationException.invalidValue();
index 7f30aa4cec62a327e0ff3de83e5e978b2428db5a..b9d679d3d364a7aecf577a98e5d3fd7f03aff488 100644 (file)
@@ -17,7 +17,6 @@
 
 package org.apache.poi.hssf.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
 import org.apache.poi.hssf.record.formula.eval.EvaluationException;
@@ -81,12 +80,8 @@ public class Mid implements Function {
 
        private static int evaluateNumberArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
                ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
-               if (ev instanceof BlankEval) {
-                       // Note - for start_num arg, blank causes error(#VALUE!),
-                       // but for num_chars causes empty string to be returned.
-                       return 0;
-               }
-
+               // Note - for start_num arg, blank/zero causes error(#VALUE!),
+               // but for num_chars causes empty string to be returned.
                return OperandResolver.coerceValueToInt(ev);
        }
 }
\ No newline at end of file
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Month.java b/src/java/org/apache/poi/hssf/record/formula/functions/Month.java
deleted file mode 100644 (file)
index d5178b2..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFDateUtil;
-
-/**
- * 
- * @author Guenter Kickinger g.kickinger@gmx.net
- *
- */
-public class Month extends NumericFunction {
-
-       /* (non-Javadoc)
-        * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
-        */
-       public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
-                    java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
-                    retval = new NumberEval(d.getMonth()+1);
-                } else {
-                    retval = ErrorEval.NUM_ERROR;
-                }
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            } else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        return retval;
-    }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/NumericFunctionOneArg.java b/src/java/org/apache/poi/hssf/record/formula/functions/NumericFunctionOneArg.java
new file mode 100644 (file)
index 0000000..0012013
--- /dev/null
@@ -0,0 +1,172 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.EvaluationException;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
+ * 
+ */
+public abstract class NumericFunctionOneArg implements Function {
+
+       public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+               if (args.length != 1) {
+                       return ErrorEval.VALUE_INVALID;
+               }
+               try {
+                       ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol);
+                       double d = OperandResolver.coerceValueToDouble(ve);
+                       if (Double.isNaN(d) || Double.isInfinite(d)) {
+                               return ErrorEval.NUM_ERROR;
+                       }
+                       double result = evaluate(d);
+                       if (Double.isNaN(result) || Double.isInfinite(result)) {
+                               return ErrorEval.NUM_ERROR;
+                       }
+                       return new NumberEval(result);
+               } catch (EvaluationException e) {
+                       return e.getErrorEval();
+               }
+       }
+
+       protected abstract double evaluate(double d);
+
+       public static final Function ABS = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.abs(d);
+               }
+       };
+       public static final Function ACOS = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.acos(d);
+               }
+       };
+       public static final Function ACOSH = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.acosh(d);
+               }
+       };
+       public static final Function ASIN = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.asin(d);
+               }
+       };
+       public static final Function ASINH = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.asinh(d);
+               }
+       };
+       public static final Function ATAN = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.atan(d);
+               }
+       };
+       public static final Function ATANH = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.atanh(d);
+               }
+       };
+       public static final Function COS = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.cos(d);
+               }
+       };
+       public static final Function COSH = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.cosh(d);
+               }
+       };
+       public static final Function DEGREES = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.toDegrees(d);
+               }
+       };
+       public static final Function DOLLAR = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return d;
+               }
+       };
+       public static final Function EXP = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.pow(Math.E, d);
+               }
+       };
+       public static final Function FACT = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.factorial((int)d);
+               }
+       };
+       public static final Function INT = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.round(d-0.5);
+               }
+       };
+       public static final Function LN = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.log(d);
+               }
+       };
+    static final double LOG_10_TO_BASE_e = Math.log(10);
+       public static final Function LOG10 = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.log(d) / LOG_10_TO_BASE_e;
+               }
+       };
+       public static final Function RADIANS = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.toRadians(d);
+               }
+       };
+       public static final Function SIGN = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.sign(d);
+               }
+       };
+       public static final Function SIN = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.sin(d);
+               }
+       };
+       public static final Function SINH = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.sinh(d);
+               }
+       };
+       public static final Function SQRT = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.sqrt(d);
+               }
+       };
+       
+       public static final Function TAN = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return Math.tan(d);
+               }
+       };
+       public static final Function TANH = new NumericFunctionOneArg() {
+               protected double evaluate(double d) {
+                       return MathX.tanh(d);
+               }
+       };
+}
index 8af68c3db5f25552f7f4df98fbcc39af354556fc..4cb8c700d141ee09b2b82b6751c2461c45da646f 100644 (file)
@@ -1,73 +1,49 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.record.formula.functions;
 
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
 
 /**
  * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
  *  
  */
-public class Odd extends NumericFunction {
+public final class Odd extends NumericFunctionOneArg {
+       private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL;
     
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        
-        if (retval == null) {
-            if (!Double.isNaN(d) && !Double.isInfinite(d)) {
-                d = (d==0) 
-                    ? 1 
-                    : ((((long) d) - 1) % 2 == 0)
-                        ? d
-                        : (d < 0) 
-                            ? ((((long) (d/2))<<1)-1) 
-                            : ((((long) (d/2))<<1)+1);
-            }
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
+       protected double evaluate(double d) {
+               if (d==0) {
+                       return 1;
+               }
+               long result;
+               if (d>0) {
+                       result = calcOdd(d);
+               } else {
+                       result = -calcOdd(-d);
+               }
+               return result;
     }
 
+       private static long calcOdd(double d) {
+               double dpm1 = d+1;
+               long x = ((long) dpm1) & PARITY_MASK;
+               if (x == dpm1) {
+                       return x-1;
+               }
+               return x + 1;
+       }
 }
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Radians.java b/src/java/org/apache/poi/hssf/record/formula/functions/Radians.java
deleted file mode 100644 (file)
index 836fab3..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *  
- */
-public class Radians extends NumericFunction {
-    
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        
-        if (retval == null) {
-            d = Math.toRadians(d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sign.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sign.java
deleted file mode 100644 (file)
index 2353cf4..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-public class Sign extends NumericFunction {
-    
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-        
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        
-        if (retval == null) {
-            retval = (Double.isNaN(d) || Double.isInfinite(d)) 
-                    ? (ValueEval) ErrorEval.VALUE_INVALID 
-                    : new NumberEval(MathX.sign(d));
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sin.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sin.java
deleted file mode 100644 (file)
index 1e76693..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Sin extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.sin(d);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java
deleted file mode 100644 (file)
index 8b03502..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Sinh extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = MathX.sinh(d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java
deleted file mode 100644 (file)
index 57ce5cf..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Sqrt extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.sqrt(d);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Tan.java b/src/java/org/apache/poi/hssf/record/formula/functions/Tan.java
deleted file mode 100644 (file)
index c8d1e33..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Tan extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = Math.tan(d);
-            retval = (Double.isNaN(d))
-                    ? (ValueEval) ErrorEval.VALUE_INVALID
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java
deleted file mode 100644 (file)
index 1cb0e4f..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
- *
- */
-public class Tanh extends NumericFunction {
-
-    public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
-        double d = 0;
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                d = ne.getNumberValue();
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            }
-            else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-
-        if (retval == null) {
-            d = MathX.tanh(d);
-            retval = (Double.isNaN(d) || Double.isInfinite(d))
-                    ? (ValueEval) ErrorEval.NUM_ERROR
-                    : new NumberEval(d);
-        }
-        return retval;
-    }
-
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Year.java b/src/java/org/apache/poi/hssf/record/formula/functions/Year.java
deleted file mode 100644 (file)
index b461a09..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFDateUtil;
-
-/**
- * 
- * @author Guenter Kickinger g.kickinger@gmx.net
- *
- */
-
-public class Year extends NumericFunction {
-
-       /* (non-Javadoc)
-        * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short)
-        */
-       public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) {
-        ValueEval retval = null;
-
-        switch (operands.length) {
-        default:
-            retval = ErrorEval.VALUE_INVALID;
-            break;
-        case 1:
-            ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol);
-            if (ve instanceof NumericValueEval) {
-                NumericValueEval ne = (NumericValueEval) ve;
-                if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) {
-                    java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem
-                    retval = new NumberEval(d.getYear()+1900);
-                } else {
-                    retval = ErrorEval.NUM_ERROR;
-                }
-            }
-            else if (ve instanceof BlankEval) {
-                // do nothing
-            } else {
-                retval = ErrorEval.NUM_ERROR;
-            }
-        }
-        return retval;
-    }
-}
\ No newline at end of file
index dd6d5b38324e224fe10fa10f02fe5945de69b8e1..54962e7f20ecd6dd0bc4f3c0a8ab9cf4f96cb8df 100644 (file)
@@ -582,7 +582,10 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
     }
 
     /**
-     * check whether a sheet is hidden
+     * Check whether a sheet is hidden.
+     * Note that a sheet could instead be 
+     *  set to be very hidden, which is different
+     *  ({@link #isSheetVeryHidden(int)})
      * @param sheetIx Number
      * @return True if sheet is hidden
      */
@@ -590,6 +593,18 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
         validateSheetIndex(sheetIx);
         return workbook.isSheetHidden(sheetIx);
     }
+    /**
+     * Check whether a sheet is very hidden.
+     * This is different from the normal 
+     *  hidden status  
+     *  ({@link #isSheetHidden(int)})
+     * @param sheetIx Number
+     * @return True if sheet is very hidden
+     */
+    public boolean isSheetVeryHidden(int sheetIx) {
+        validateSheetIndex(sheetIx);
+        return workbook.isSheetVeryHidden(sheetIx);
+    }
 
     /**
      * Hide or unhide a sheet
@@ -601,6 +616,19 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
         validateSheetIndex(sheetIx);
         workbook.setSheetHidden(sheetIx, hidden);
     }
+    /**
+     * Hide or unhide a sheet.
+     *  0 = not hidden
+     *  1 = hidden
+     *  2 = very hidden.
+     * 
+     * @param sheetIx The sheet number
+     * @param hidden 0 for not hidden, 1 for hidden, 2 for very hidden
+     */
+    public void setSheetHidden(int sheetIx, int hidden) {
+        validateSheetIndex(sheetIx);
+        workbook.setSheetHidden(sheetIx, hidden);
+    }
 
     /*
      * get the sheet's index
@@ -708,8 +736,8 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
             HSSFName newName = new HSSFName(this, newNameRecord);
             names.add(newName);
 
-            workbook.cloneDrawings(clonedSheet.getSheet());
         }
+        workbook.cloneDrawings(clonedSheet.getSheet());
         // TODO - maybe same logic required for other/all built-in name records
         
         return clonedSheet;
@@ -1020,13 +1048,7 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
             if (!r.isBuiltInName() || r.getBuiltInName() != builtinCode) {
                 continue;
             }
-            if(r.getSheetNumber() == 0) {
-                //ignore "GLOBAL" name records
-                continue;
-            }
-            int externIndex = r.getSheetNumber() -1;
-            int nameRecordSheetIndex = workbook.getSheetIndexFromExternSheetIndex(externIndex);
-            if (nameRecordSheetIndex == sheetIndex) {
+            if (r.getSheetNumber() -1 == sheetIndex) {
                 return defNameIndex;
             }
         }
index daf1c8e1720736a3c3b9470dd4563fd424ff371c..f1898c082be7b78966a7a09898d93b451c102521 100644 (file)
@@ -103,6 +103,9 @@ public class HWPFDocument extends POIDocument
   /** Escher Drawing Group information */
   protected EscherRecordHolder _dgg;
 
+  /** Holds Office Art objects */
+  protected ShapesTable _officeArts;
+
   protected HWPFDocument()
   {
      super(null, null);
@@ -252,6 +255,8 @@ public class HWPFDocument extends POIDocument
     
     // read in the pictures stream
     _pictures = new PicturesTable(this, _dataStream, _mainStream, _fspa, _dgg);
+    // And the art shapes stream
+    _officeArts = new ShapesTable(_tableStream, _fib);
 
     _st = new SectionTable(_mainStream, _tableStream, _fib.getFcPlcfsed(), _fib.getLcbPlcfsed(), fcMin, _tpt, _cpSplit);
     _ss = new StyleSheet(_tableStream, _fib.getFcStshf());
@@ -392,6 +397,13 @@ public class HWPFDocument extends POIDocument
   public PicturesTable getPicturesTable() {
          return _pictures;
   }
+  
+  /**
+   * @return ShapesTable object, that is able to extract office are shapes from this document
+   */
+  public ShapesTable getShapesTable() {
+         return _officeArts;
+  }
 
   /**
    * Writes out the word file that is represented by an instance of this class.
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java
new file mode 100644 (file)
index 0000000..998ea2d
--- /dev/null
@@ -0,0 +1,54 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.hwpf.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hwpf.usermodel.Shape;
+
+public class ShapesTable {
+        private List _shapes;
+        private List _shapesVisibili;  //holds visible shapes
+
+        public ShapesTable(byte [] tblStream, FileInformationBlock fib) {
+                PlexOfCps binTable = new PlexOfCps(tblStream,
+                     fib.getFcPlcspaMom(), fib.getLcbPlcspaMom(), 26);
+
+                _shapes = new ArrayList();
+                _shapesVisibili = new ArrayList();
+
+
+                for(int i = 0; i < binTable.length(); i++) {
+                        GenericPropertyNode nodo = binTable.getProperty(i);
+
+                        Shape sh = new Shape(nodo);
+                        _shapes.add(sh);
+                        if(sh.isWithinDocument())
+                                _shapesVisibili.add(sh);
+                }
+        }
+
+        public List getAllShapes() {
+                return _shapes;
+        }
+
+        public List getVisibleShapes() {
+                return _shapesVisibili;
+        }
+}
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java
new file mode 100644 (file)
index 0000000..1f798b6
--- /dev/null
@@ -0,0 +1,74 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.hwpf.usermodel;
+
+import org.apache.poi.hwpf.model.GenericPropertyNode;
+import org.apache.poi.util.LittleEndian;
+
+public class Shape {
+        int _id, _left, _right, _top, _bottom;
+        /**
+         * true if the Shape bounds are within document (for
+         * example, it's false if the image left corner is outside the doc, like for
+         * embedded documents)
+         */
+        boolean _inDoc; 
+
+        public Shape(GenericPropertyNode nodo) {
+                byte [] contenuto = nodo.getBytes();
+                _id = LittleEndian.getInt(contenuto);
+                _left = LittleEndian.getInt(contenuto, 4);
+                _top = LittleEndian.getInt(contenuto, 8);
+                _right = LittleEndian.getInt(contenuto, 12);
+                _bottom = LittleEndian.getInt(contenuto, 16);
+                _inDoc = (_left >= 0 && _right >= 0 && _top >= 0 && _bottom >=
+0);
+        }
+
+        public int getId() {
+                return _id;
+        }
+
+        public int getLeft() {
+                return _left;
+        }
+
+        public int getRight() {
+                return _right;
+        }
+
+        public int getTop() {
+                return _top;
+        }
+
+        public int getBottom() {
+                return _bottom;
+        }
+
+        public int getWidth() {
+                return _right - _left + 1;
+        }
+
+        public int getHeight() {
+                return _bottom - _top + 1;
+        }
+
+        public boolean isWithinDocument() {
+                return _inDoc;
+        }
+}
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc b/src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc
new file mode 100644 (file)
index 0000000..27793c3
Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc differ
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java
new file mode 100644 (file)
index 0000000..273a034
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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.hwpf.usermodel;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.hwpf.HWPFDocument;
+
+/**
+ * Test the shapes handling
+ */
+public class TestShapes extends TestCase {
+       private String dirname = System.getProperty("HWPF.testdata.path");
+
+    /**
+     * two shapes, second is a group
+     */
+    public void testShapes() throws Exception {
+       HWPFDocument doc = new HWPFDocument(new FileInputStream(dirname + "/WithArtShapes.doc"));
+
+               List shapes = doc.getShapesTable().getAllShapes();
+               List vshapes = doc.getShapesTable().getVisibleShapes();
+
+               assertEquals(2, shapes.size());
+               assertEquals(2, vshapes.size());
+
+               Shape s1 = (Shape)shapes.get(0);
+               Shape s2 = (Shape)shapes.get(1);
+
+               assertEquals(3616, s1.getWidth());
+               assertEquals(1738, s1.getHeight());
+               assertEquals(true, s1.isWithinDocument());
+
+               assertEquals(4817, s2.getWidth());
+               assertEquals(2164, s2.getHeight());
+               assertEquals(true, s2.isWithinDocument());
+       
+               
+               // Re-serialisze, check still there
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               doc.write(baos);
+               ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+               doc = new HWPFDocument(bais);
+               
+               shapes = doc.getShapesTable().getAllShapes();
+               vshapes = doc.getShapesTable().getVisibleShapes();
+
+               assertEquals(2, shapes.size());
+               assertEquals(2, vshapes.size());
+
+               s1 = (Shape)shapes.get(0);
+               s2 = (Shape)shapes.get(1);
+
+               assertEquals(3616, s1.getWidth());
+               assertEquals(1738, s1.getHeight());
+               assertEquals(true, s1.isWithinDocument());
+
+               assertEquals(4817, s2.getWidth());
+               assertEquals(2164, s2.getHeight());
+               assertEquals(true, s2.isWithinDocument());
+
+    }
+}
diff --git a/src/testcases/org/apache/poi/hssf/data/45761.xls b/src/testcases/org/apache/poi/hssf/data/45761.xls
new file mode 100644 (file)
index 0000000..ee44612
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/45761.xls differ
index 99cb61a58811b2246af6cc66651997d897dffe0c..e4c8e42dcbc4679e72ef4d458fe7686fc19333dd 100644 (file)
Binary files a/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls and b/src/testcases/org/apache/poi/hssf/data/FormulaEvalTestData.xls differ
index fc81e60a18397f0a47b49bb77c3e32309d15662d..b8dabbf718f7a524de0d14a36c1615e5c9b6b99c 100755 (executable)
Binary files a/src/testcases/org/apache/poi/hssf/data/externalFunctionExample.xls and b/src/testcases/org/apache/poi/hssf/data/externalFunctionExample.xls differ
diff --git a/src/testcases/org/apache/poi/hssf/data/testRRaC.xls b/src/testcases/org/apache/poi/hssf/data/testRRaC.xls
new file mode 100644 (file)
index 0000000..25939e8
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/testRRaC.xls differ
index 1f6d0d3c282867f44c8abb9b96d343ba884ce90f..c1087c1fc476000d875b26654da693425549ed67 100755 (executable)
@@ -77,8 +77,9 @@ public final class TestExternalFunctionFormulas extends TestCase {
                HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
                confirmCellEval(sheet, 0, 0, fe, "YEARFRAC(B1,C1)", 29.0/90.0);
                confirmCellEval(sheet, 1, 0, fe, "YEARFRAC(B2,C2)", 0.0);
-               confirmCellEval(sheet, 2, 0, fe, "IF(ISEVEN(3),1.2,1.6)", 1.6);
-               confirmCellEval(sheet, 3, 0, fe, "IF(ISODD(3),1.2,1.6)", 1.2);
+               confirmCellEval(sheet, 2, 0, fe, "YEARFRAC(B3,C3,D3)", 0.0);
+               confirmCellEval(sheet, 3, 0, fe, "IF(ISEVEN(3),1.2,1.6)", 1.6);
+               confirmCellEval(sheet, 4, 0, fe, "IF(ISODD(3),1.2,1.6)", 1.2);
        }
 
        private static void confirmCellEval(HSSFSheet sheet, int rowIx, int colIx, 
index 1b5e4cd5dce710d7d70b3fb0a5c7171fe7cbe49e..200e62884abcab9810cdeb825998c3b1ba3aaa0e 100644 (file)
@@ -1383,4 +1383,31 @@ public final class TestBugs extends TestCase {
         assertFalse(nwb.getSheetAt(1).getForceFormulaRecalculation());
         assertTrue(nwb.getSheetAt(2).getForceFormulaRecalculation());
     }
+    
+    /**
+     * Very hidden sheets not displaying as such
+     */
+    public void test45761() {
+       HSSFWorkbook wb = openSample("45761.xls");
+       assertEquals(3, wb.getNumberOfSheets());
+       
+       assertFalse(wb.isSheetHidden(0));
+       assertFalse(wb.isSheetVeryHidden(0));
+       assertTrue(wb.isSheetHidden(1));
+       assertFalse(wb.isSheetVeryHidden(1));
+       assertFalse(wb.isSheetHidden(2));
+       assertTrue(wb.isSheetVeryHidden(2));
+       
+       // Change 0 to be very hidden, and re-load
+       wb.setSheetHidden(0, 2);
+       
+        HSSFWorkbook nwb = writeOutAndReadBack(wb);
+
+       assertFalse(nwb.isSheetHidden(0));
+       assertTrue(nwb.isSheetVeryHidden(0));
+       assertTrue(nwb.isSheetHidden(1));
+       assertFalse(nwb.isSheetVeryHidden(1));
+       assertFalse(nwb.isSheetHidden(2));
+       assertTrue(nwb.isSheetVeryHidden(2));
+    }
 }
index 1717aeff655565e81133eb4158273cba25033723..6fb08f4ee30857a7000c72005e08c321f615a202 100644 (file)
@@ -527,4 +527,33 @@ public final class TestHSSFWorkbook extends TestCase {
             }
         }
     }
+    
+    /**
+     * Test to make sure that NameRecord.getSheetNumber() is interpreted as a
+     * 1-based sheet tab index (not a 1-based extern sheet index)
+     */
+    public void testFindBuiltInNameRecord() {
+        // testRRaC has multiple (3) built-in name records
+        // The second print titles name record has getSheetNumber()==4
+        HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("testRRaC.xls");
+        NameRecord nr;
+        assertEquals(3, wb.getWorkbook().getNumNames());
+        nr = wb.getWorkbook().getNameRecord(2);
+        // TODO - render full row and full column refs properly
+        assertEquals("Sheet2!$A$1:$IV$1", nr.getAreaReference(wb)); // 1:1
+        
+        try {
+            wb.setRepeatingRowsAndColumns(3, 4, 5, 8, 11);
+        } catch (RuntimeException e) {
+            if (e.getMessage().equals("Builtin (7) already exists for sheet (4)")) {
+                // there was a problem in the code which locates the existing print titles name record 
+                throw new RuntimeException("Identified bug 45720b");
+            }
+            throw e;
+        }
+        wb = HSSFTestDataSamples.writeOutAndReadBack(wb);
+        assertEquals(3, wb.getWorkbook().getNumNames());
+        nr = wb.getWorkbook().getNameRecord(2);
+        assertEquals("Sheet2!E:F,Sheet2!$A$9:$IV$12", nr.getAreaReference(wb)); // E:F,9:12
+    }
 }