From 02ad8e1958bed72c50efab75d12bd5fc1393b683 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 9 Sep 2008 16:49:30 +0000 Subject: [PATCH] Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-658321,658323-658335,658337-658348,658351,658353-658832,658834-658983,658985,658987-659066,659068-659402,659404-659428,659430-659451,659453-659454,659456-659461,659463-659477,659479-659524,659526-659571,659574,659576-660255,660257-660262,660264-660279,660281-660343,660345-660473,660475-660827,660829-660833,660835-660888,660890-663321,663323-663435,663437-663764,663766-663854,663856-664219,664221-664489,664494-664514,664516-668013,668015-668142,668144-668152,668154,668156-668256,668258,668260-669139,669141-669455,669457-669657,669659-669808,669810-670189,670191-671321,671323-672229,672231-672549,672551-672552,672554-672561,672563-672566,672568,672571-673049,673051-673852,673854-673862,673864-673986,673988-673996,673998-674347,674349-674890,674892-674910,674912-674936,674938-674952,674954-675078,675080-675085,675087-675217,675219-675660,675662-675670,675672-675716,675718-675726,675728-675733,675735-675775,675777-675782,675784,675786-675791,675794-675852,675854-676200,676202,676204,676206-676220,676222-676309,676311-676456,676458-676994,676996-677027,677030-677040,677042-677056,677058-677375,677377-677968,677970-677971,677973,677975-677994,677996-678286,678288-678538,678540-680393,680395-680469,680471-680529,680531-680852,680854-681529,681531-681571,681573-682224,682226,682228,682231-682281,682283-682335,682337-682507,682509,682512-682517,682519-682532,682534-682619,682622-682777,682779-682998,683000-683019,683021-683022,683024-683080,683082-683092,683094-683095,683097-683127,683129-683131,683133-683166,683168-683698,683700-683705,683707-683757,683759-683787,683789-683870,683872-683879,683881-683900,683902-684066,684068-684074,684076-684222,684224-684254,684257-684281,684283-684286,684288-684292,684294-684298,684300-684301,684303-684308,684310-684317,684320,684323-684335,684337-684348,684350-684354,684356-684361,684363-684369,684371-684453,684455-684883,684885-684937,684940-684958,684960-684970,684972-684985,684987-685053,685055-685063,685065-685259,685261-685262,685264-685266,685268-685282,685285-686035,686037-686045,686047-686052,686054-686206,686208-686215,686217-686277,686279-686289,686291-686620,686622-686623,686626-686627,686629-686639,686641-686843,686845-686976,686978-687402,687404-687422,687424-687428,687430-687442,687444-688425,688427-688641,688643-688649,688651-688654,688656-688824,688826-688909,688911-689543,689545-689558,689560-689635,689637-689703,689705-689715,689717-689718,689720,689722-689972,689974-690090,690092-690093,690095-690111,690113-690258,690260-690261,690263-690403,690405-690410,690412-690460,690462-690516,690518-690533,690535,690537-690625,690627-690635,690637-690720,690722-690725,690727-690728,690730-690738,690740-690760,690762-690771,690773-690824,690826-690834,690838-691016,691018-691179,691181,691183-691532,691534-691686,691688-691739,691741-692238,692240,692242,692244-692254,692256-692299,692301-692505,692507-692537,692539-692540,692542-692611,692613,692615-692892,692894-693438 via svnmerge from 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 --- src/documentation/content/xdocs/changes.xml | 6 +- src/documentation/content/xdocs/status.xml | 6 +- .../apache/poi/ddf/EscherContainerRecord.java | 7 +- .../org/apache/poi/hssf/model/Workbook.java | 56 +++++- .../poi/hssf/record/BoundSheetRecord.java | 21 +++ .../apache/poi/hssf/record/NameRecord.java | 15 +- .../poi/hssf/record/formula/Area3DPtg.java | 1 + .../record/formula/atp/ParityFunction.java | 3 - .../poi/hssf/record/formula/atp/YearFrac.java | 3 - .../record/formula/eval/FunctionEval.java | 52 +++--- .../record/formula/eval/OperandResolver.java | 18 +- .../hssf/record/formula/eval/PercentEval.java | 11 +- .../eval/TwoOperandNumericOperation.java | 25 ++- .../record/formula/eval/UnaryMinusEval.java | 11 +- .../record/formula/eval/UnaryPlusEval.java | 37 ++-- .../hssf/record/formula/functions/Abs.java | 67 ------- .../hssf/record/formula/functions/Acos.java | 67 ------- .../hssf/record/formula/functions/Acosh.java | 65 ------- .../hssf/record/formula/functions/Asin.java | 67 ------- .../hssf/record/formula/functions/Asinh.java | 71 -------- .../hssf/record/formula/functions/Atan.java | 67 ------- .../hssf/record/formula/functions/Atanh.java | 70 ------- .../functions/CalendarFieldFunction.java | 92 ++++++++++ .../hssf/record/formula/functions/Cos.java | 65 ------- .../hssf/record/formula/functions/Cosh.java | 65 ------- .../hssf/record/formula/functions/Day.java | 64 ------- .../record/formula/functions/Degrees.java | 65 ------- .../hssf/record/formula/functions/Dollar.java | 64 ------- .../hssf/record/formula/functions/Even.java | 102 ++++------- .../hssf/record/formula/functions/Exp.java | 65 ------- .../hssf/record/formula/functions/Fact.java | 74 -------- .../hssf/record/formula/functions/Int.java | 69 ------- .../poi/hssf/record/formula/functions/Ln.java | 66 ------- .../hssf/record/formula/functions/Log10.java | 68 ------- .../record/formula/functions/LookupUtils.java | 26 ++- .../hssf/record/formula/functions/Mid.java | 9 +- .../hssf/record/formula/functions/Month.java | 67 ------- .../functions/NumericFunctionOneArg.java | 172 ++++++++++++++++++ .../hssf/record/formula/functions/Odd.java | 100 ++++------ .../record/formula/functions/Radians.java | 65 ------- .../hssf/record/formula/functions/Sign.java | 62 ------- .../hssf/record/formula/functions/Sin.java | 67 ------- .../hssf/record/formula/functions/Sinh.java | 67 ------- .../hssf/record/formula/functions/Sqrt.java | 67 ------- .../hssf/record/formula/functions/Tan.java | 67 ------- .../hssf/record/formula/functions/Tanh.java | 67 ------- .../hssf/record/formula/functions/Year.java | 68 ------- .../poi/hssf/usermodel/HSSFWorkbook.java | 40 +++- .../src/org/apache/poi/hwpf/HWPFDocument.java | 12 ++ .../apache/poi/hwpf/model/ShapesTable.java | 54 ++++++ .../org/apache/poi/hwpf/usermodel/Shape.java | 74 ++++++++ .../apache/poi/hwpf/data/WithArtShapes.doc | Bin 0 -> 53760 bytes .../apache/poi/hwpf/usermodel/TestShapes.java | 83 +++++++++ .../org/apache/poi/hssf/data/45761.xls | Bin 0 -> 15872 bytes .../poi/hssf/data/FormulaEvalTestData.xls | Bin 153600 -> 154624 bytes .../poi/hssf/data/externalFunctionExample.xls | Bin 16896 -> 16896 bytes .../org/apache/poi/hssf/data/testRRaC.xls | Bin 0 -> 20480 bytes .../formula/TestExternalFunctionFormulas.java | 5 +- .../apache/poi/hssf/usermodel/TestBugs.java | 27 +++ .../poi/hssf/usermodel/TestHSSFWorkbook.java | 29 +++ 60 files changed, 835 insertions(+), 1998 deletions(-) delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Abs.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Acos.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Asin.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Asinh.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Atan.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Atanh.java create mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Cos.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Cosh.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Day.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Exp.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Fact.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Int.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Ln.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Log10.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Month.java create mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/NumericFunctionOneArg.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Radians.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Sign.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Sin.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Tan.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java delete mode 100644 src/java/org/apache/poi/hssf/record/formula/functions/Year.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java create mode 100644 src/scratchpad/testcases/org/apache/poi/hwpf/data/WithArtShapes.doc create mode 100644 src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java create mode 100644 src/testcases/org/apache/poi/hssf/data/45761.xls create mode 100644 src/testcases/org/apache/poi/hssf/data/testRRaC.xls diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index a78c832e5..c1152ef34 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -65,8 +65,10 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx - 45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings - 45728 Fix for SlideShow.reorderSlide in HSLF + 45761 - Support for Very Hidden excel sheets in HSSF + 45738 - Initial HWPF support for Office Art Shapes + 45720 - Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings + 45728 - Fix for SlideShow.reorderSlide in HSLF Initial support for embedded movies and controls in HSLF 45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF() Support for HPBF Publisher hyperlinks, including during text extraction diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 85bda8b74..155d522d7 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -62,8 +62,10 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx - 45720 Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings - 45728 Fix for SlideShow.reorderSlide in HSLF + 45761 - Support for Very Hidden excel sheets in HSSF + 45738 - Initial HWPF support for Office Art Shapes + 45720 - Fixed HSSFWorkbook.cloneSheet to correctly clone sheets with drawings + 45728 - Fix for SlideShow.reorderSlide in HSLF Initial support for embedded movies and controls in HSLF 45358 - signed/unsigned error when parsing 3-d area refs, performance problem evaluating area refs, and ClassCastExcecption in IF() Support for HPBF Publisher hyperlinks, including during text extraction diff --git a/src/java/org/apache/poi/ddf/EscherContainerRecord.java b/src/java/org/apache/poi/ddf/EscherContainerRecord.java index bb188d538..9c204226e 100644 --- a/src/java/org/apache/poi/ddf/EscherContainerRecord.java +++ b/src/java/org/apache/poi/ddf/EscherContainerRecord.java @@ -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); } } diff --git a/src/java/org/apache/poi/hssf/model/Workbook.java b/src/java/org/apache/poi/hssf/model/Workbook.java index f093feef6..7976588d3 100644 --- a/src/java/org/apache/poi/hssf/model/Workbook.java +++ b/src/java/org/apache/poi/hssf/model/Workbook.java @@ -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); } } diff --git a/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java b/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java index 2ef4c67d2..1f7106ad7 100644 --- a/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java +++ b/src/java/org/apache/poi/hssf/record/BoundSheetRecord.java @@ -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); + } } diff --git a/src/java/org/apache/poi/hssf/record/NameRecord.java b/src/java/org/apache/poi/hssf/record/NameRecord.java index 77296becd..0716c448d 100644 --- a/src/java/org/apache/poi/hssf/record/NameRecord.java +++ b/src/java/org/apache/poi/hssf/record/NameRecord.java @@ -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"); diff --git a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java index ba207ab5c..8848cb603 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java +++ b/src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java @@ -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()); diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java b/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java index 9dd6d0981..71cfa0359 100644 --- a/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java +++ b/src/java/org/apache/poi/hssf/record/formula/atp/ParityFunction.java @@ -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; diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java b/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java index 96718ef4e..f5bc3fe8f 100644 --- a/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java +++ b/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java @@ -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); } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java index fe58c69c0..a1c7356fa 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java @@ -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 diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java b/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java index 627b26998..87f45236b 100755 --- a/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java @@ -171,7 +171,8 @@ public final class OperandResolver { /** * Applies some conversion rules if the supplied value is not already an integer.
- * Value is first coerced to a double ( See coerceValueToDouble() ).

+ * Value is first coerced to a double ( See coerceValueToDouble() ). + * Note - BlankEval is converted to 0.

* * Excel typically converts doubles to integers by truncating toward negative infinity.
* The equivalent java code is:
@@ -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 - BlankEval is not supported and must be handled by the caller. - * @param ev must be a NumberEval, StringEval or BoolEval + * Note - BlankEval 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 parseDouble() for allowable formats). - * @throws RuntimeException if the supplied parameter is not NumberEval, - * StringEval or BoolEval + * @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(); diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java index d03e44745..d8a579c42 100755 --- a/src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java @@ -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"); + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/TwoOperandNumericOperation.java b/src/java/org/apache/poi/hssf/record/formula/eval/TwoOperandNumericOperation.java index 665ba4b46..0f2933fae 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/TwoOperandNumericOperation.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/TwoOperandNumericOperation.java @@ -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; diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java index 8174429e0..780334ae8 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java @@ -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"); + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java index 66c5f6801..831d34286 100644 --- a/src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java +++ b/src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java @@ -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 index 1bebb358b..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Abs.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index bc5b5720e..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Acos.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 794516e57..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java +++ /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 < amolweb at ya hoo dot com > - * 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 index 868ff7a8d..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Asin.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 8814dc3f8..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Asinh.java +++ /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 < amolweb at ya hoo dot com > - * 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 index 8266ad24d..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Atan.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index d472b1f00..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Atanh.java +++ /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 < amolweb at ya hoo dot com > - * 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 index 000000000..b1ea02fdc --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/CalendarFieldFunction.java @@ -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 index f26279766..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Cos.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 41c865069..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Cosh.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 0ae569476..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Day.java +++ /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 index e85e14d56..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index a65f65a3e..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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; - } - -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Even.java b/src/java/org/apache/poi/hssf/record/formula/functions/Even.java index 914967167..272863908 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Even.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Even.java @@ -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 < amolweb at ya hoo dot com > * */ -public class Even extends NumericFunction { +public final class Even extends NumericFunctionOneArg { - 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; - } + private static final long PARITY_MASK = 0xFFFFFFFFFFFFFFFEL; + 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 index d0b122ab1..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Exp.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 128b167c6..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Fact.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 5b26a8a8a..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Int.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 95392a4d1..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Ln.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index cf8b9bd13..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Log10.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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; - } - -} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java b/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java index ee67ef8ec..613a3d144 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java @@ -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(); diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mid.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mid.java index 7f30aa4ce..b9d679d3d 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Mid.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mid.java @@ -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 index d5178b22d..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Month.java +++ /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 index 000000000..001201394 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/NumericFunctionOneArg.java @@ -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 < amolweb at ya hoo dot com > + * + */ +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); + } + }; +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Odd.java b/src/java/org/apache/poi/hssf/record/formula/functions/Odd.java index 8af68c3db..4cb8c700d 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Odd.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Odd.java @@ -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 < amolweb at ya hoo dot com > * */ -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 index 836fab3ad..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Radians.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 2353cf47f..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Sign.java +++ /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 index 1e7669302..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Sin.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 8b0350286..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 57ce5cf48..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index c8d1e33e5..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Tan.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index 1cb0e4fa2..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java +++ /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 < amolweb at ya hoo dot com > - * - */ -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 index b461a0966..000000000 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Year.java +++ /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 diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index dd6d5b383..54962e7f2 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -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; } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index daf1c8e17..f1898c082 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -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 index 000000000..998ea2d8f --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/ShapesTable.java @@ -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 index 000000000..1f798b620 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Shape.java @@ -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 index 0000000000000000000000000000000000000000..27793c37a4605ddb4f206acf2134b088f8f5f4b7 GIT binary patch literal 53760 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 literal 0 HcmV?d00001 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 index 000000000..273a03432 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestShapes.java @@ -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 index 0000000000000000000000000000000000000000..ee44612c40326655b9f8769e3838ea40e33f0728 GIT binary patch literal 15872 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 YD*0?$(CqndR#mH8G}zU8pW-n58@p#$P5=M^ delta 4592 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 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 index 0000000000000000000000000000000000000000..25939e85f6e3b0698d4a2a1062ece21d805802d7 GIT binary patch literal 20480 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 AF8}}l literal 0 HcmV?d00001 diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java b/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java index 1f6d0d3c2..c1087c1fc 100755 --- a/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java +++ b/src/testcases/org/apache/poi/hssf/record/formula/TestExternalFunctionFormulas.java @@ -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, diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 1b5e4cd5d..200e62884 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -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)); + } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java index 1717aeff6..6fb08f4ee 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java @@ -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 + } }