From 41b294edbf16b4819856560ac0c889fd6cf9b506 Mon Sep 17 00:00:00 2001
From: Yegor Kozlov true
if a change was made to the formula tokens
- */
- public boolean adjustFormula(Ptg[] ptgs, int currentExternSheetIx) {
- boolean refsWereChanged = false;
- for(int i=0; iPtg
- * tokens into human readable text form. In formula expressions, a sheet name always has a
- * trailing '!' so there is little chance for ambiguity. It doesn't matter too much what this
- * method returns but it is worth noting the likely consumers of these formula text strings:
- *
- *
- *
- * At the time of writing, POI's formula parser tolerates cell-like sheet names in formulas
- * with or without delimiters. The same goes for Excel(2007), both manual and automated entry.
- *
- * For better or worse this implementation attempts to replicate Excel's formula renderer.
- * Excel uses range checking on the apparent 'row' and 'column' components. Note however that
- * the maximum sheet size varies across versions.
- * @see org.apache.poi.hssf.util.CellReference
- */
- /* package */ static boolean cellReferenceIsWithinRange(String lettersPrefix, String numbersSuffix) {
- return CellReference.cellReferenceIsWithinRange(lettersPrefix, numbersSuffix, SpreadsheetVersion.EXCEL97);
- }
-
- /**
- * Note - this method assumes the specified rawSheetName has only letters and digits. It
- * cannot be used to match absolute or range references (using the dollar or colon char).
- *
- * Some notable cases:
- *
- *
- * @return
- *
- * Input Result Comments
- * "A1" true
- * "a111" true
- * "AA" false
- * "aa1" true
- * "A1A" false
- * "A1A1" false
- * "A$1:$C$20" false Not a plain cell reference
- * "SALES20080101" true
- * Still needs delimiting even though well out of range true
if there is any possible ambiguity that the specified rawSheetName
- * could be interpreted as a valid cell name.
- */
- /* package */ static boolean nameLooksLikePlainCellReference(String rawSheetName) {
- Matcher matcher = CELL_REF_PATTERN.matcher(rawSheetName);
- if(!matcher.matches()) {
- return false;
- }
-
- // rawSheetName == "Sheet1" gets this far.
- String lettersPrefix = matcher.group(1);
- String numbersSuffix = matcher.group(2);
- return cellReferenceIsWithinRange(lettersPrefix, numbersSuffix);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/TblPtg.java b/src/java/org/apache/poi/hssf/record/formula/TblPtg.java
index 280bd9c010..aba7129bc5 100644
--- a/src/java/org/apache/poi/hssf/record/formula/TblPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/TblPtg.java
@@ -17,7 +17,6 @@
package org.apache.poi.hssf.record.formula;
-import org.apache.poi.hssf.record.RecordFormatException;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
@@ -69,7 +68,7 @@ public final class TblPtg extends ControlPtg {
public String toFormulaString()
{
// table(....)[][]
- throw new RecordFormatException("Table and Arrays are not yet supported");
+ throw new RuntimeException("Table and Arrays are not yet supported");
}
public String toString() {
diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java b/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java
deleted file mode 100644
index 76e4edfeda..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/atp/AnalysisToolPak.java
+++ /dev/null
@@ -1,164 +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.atp;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-import org.apache.poi.hssf.record.formula.udf.UDFFinder;
-import org.apache.poi.ss.formula.OperationEvaluationContext;
-import org.apache.poi.ss.formula.eval.NotImplementedException;
-
-/**
- * @author Josh Micich
- * @author Petr Udalau - systematized work of add-in libraries and user defined functions.
- */
-public final class AnalysisToolPak implements UDFFinder {
-
- public static final UDFFinder instance = new AnalysisToolPak();
-
- private static final class NotImplemented implements FreeRefFunction {
- private final String _functionName;
-
- public NotImplemented(String functionName) {
- _functionName = functionName;
- }
-
- public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
- throw new NotImplementedException(_functionName);
- }
- };
-
- private final Map
- *
- * @author Josh Micich
- */
-final class ParityFunction implements FreeRefFunction {
-
- public static final FreeRefFunction IS_EVEN = new ParityFunction(0);
- public static final FreeRefFunction IS_ODD = new ParityFunction(1);
- private final int _desiredParity;
-
- private ParityFunction(int desiredParity) {
- _desiredParity = desiredParity;
- }
-
- public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
- if (args.length != 1) {
- return ErrorEval.VALUE_INVALID;
- }
-
- int val;
- try {
- val = evaluateArgParity(args[0], ec.getRowIndex(), ec.getColumnIndex());
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
-
- return BoolEval.valueOf(val == _desiredParity);
- }
-
- private static int evaluateArgParity(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short)srcCellCol);
-
- double d = OperandResolver.coerceValueToDouble(ve);
- if (d < 0) {
- d = -d;
- }
- long v = (long) Math.floor(d);
- return (int) (v & 0x0001);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/RandBetween.java b/src/java/org/apache/poi/hssf/record/formula/atp/RandBetween.java
deleted file mode 100644
index 2f51f72e28..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/atp/RandBetween.java
+++ /dev/null
@@ -1,84 +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.atp;
-
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-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.record.formula.functions.FreeRefFunction;
-import org.apache.poi.ss.formula.OperationEvaluationContext;
-
-/**
- * Implementation of Excel 'Analysis ToolPak' function RANDBETWEEN()
- *
- * Returns a random integer number between the numbers you specify.
- *
- * Syntax
- * RANDBETWEEN(bottom, top)
- *
- * bottom is the smallest integer RANDBETWEEN will return.
- * top is the largest integer RANDBETWEEN will return.
-
- * @author Brendan Nolan
- */
-final class RandBetween implements FreeRefFunction{
-
- public static final FreeRefFunction instance = new RandBetween();
-
- private RandBetween() {
- //enforces singleton
- }
-
- /**
- * Evaluate for RANDBETWEEN(). Must be given two arguments. Bottom must be greater than top.
- * Bottom is rounded up and top value is rounded down. After rounding top has to be set greater
- * than top.
- *
- * @see org.apache.poi.hssf.record.formula.functions.FreeRefFunction#evaluate(org.apache.poi.hssf.record.formula.eval.ValueEval[], org.apache.poi.ss.formula.OperationEvaluationContext)
- */
- public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
-
- double bottom, top;
-
- if (args.length != 2) {
- return ErrorEval.VALUE_INVALID;
- }
-
- try {
- bottom = OperandResolver.coerceValueToDouble(OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec.getColumnIndex()));
- top = OperandResolver.coerceValueToDouble(OperandResolver.getSingleValue(args[1], ec.getRowIndex(), ec.getColumnIndex()));
- if(bottom > top) {
- return ErrorEval.NUM_ERROR;
- }
- } catch (EvaluationException e) {
- return ErrorEval.VALUE_INVALID;
- }
-
- bottom = Math.ceil(bottom);
- top = Math.floor(top);
-
- if(bottom > top) {
- top = bottom;
- }
-
- return new NumberEval((bottom + (int)(Math.random() * ((top - bottom) + 1))));
-
- }
-
-}
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
deleted file mode 100644
index d36b05a36b..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/atp/YearFrac.java
+++ /dev/null
@@ -1,159 +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.atp;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.regex.Pattern;
-
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-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.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-import org.apache.poi.ss.formula.OperationEvaluationContext;
-import org.apache.poi.ss.usermodel.DateUtil;
-/**
- * Implementation of Excel 'Analysis ToolPak' function YEARFRAC()
- *
- * Returns the fraction of the year spanned by two dates.
- *
- * Syntax
- * YEARFRAC(startDate, endDate, basis)
- *
- * The basis optionally specifies the behaviour of YEARFRAC as follows:
- *
- *
- *
- *
- */
-final class YearFrac implements FreeRefFunction {
-
- public static final FreeRefFunction instance = new YearFrac();
-
- private YearFrac() {
- // enforce singleton
- }
-
- public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
- int srcCellRow = ec.getRowIndex();
- int srcCellCol = ec.getColumnIndex();
- double result;
- try {
- int basis = 0; // default
- switch(args.length) {
- case 3:
- basis = evaluateIntArg(args[2], srcCellRow, srcCellCol);
- case 2:
- break;
- default:
- return ErrorEval.VALUE_INVALID;
- }
- double startDateVal = evaluateDateArg(args[0], srcCellRow, srcCellCol);
- double endDateVal = evaluateDateArg(args[1], srcCellRow, srcCellCol);
- result = YearFracCalculator.calculate(startDateVal, endDateVal, basis);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
-
- return new NumberEval(result);
- }
-
- private static double evaluateDateArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol);
-
- if (ve instanceof StringEval) {
- String strVal = ((StringEval) ve).getStringValue();
- Double dVal = OperandResolver.parseDouble(strVal);
- if (dVal != null) {
- return dVal.doubleValue();
- }
- Calendar date = parseDate(strVal);
- return DateUtil.getExcelDate(date, false);
- }
- return OperandResolver.coerceValueToDouble(ve);
- }
-
- private static Calendar parseDate(String strVal) throws EvaluationException {
- String[] parts = Pattern.compile("/").split(strVal);
- if (parts.length != 3) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- String part2 = parts[2];
- int spacePos = part2.indexOf(' ');
- if (spacePos > 0) {
- // drop time portion if present
- part2 = part2.substring(0, spacePos);
- }
- int f0;
- int f1;
- int f2;
- try {
- f0 = Integer.parseInt(parts[0]);
- f1 = Integer.parseInt(parts[1]);
- f2 = Integer.parseInt(part2);
- } catch (NumberFormatException e) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- if (f0<0 || f1<0 || f2<0 || (f0>12 && f1>12 && f2>12)) {
- // easy to see this cannot be a valid date
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
-
- if (f0 >= 1900 && f0 < 9999) {
- // when 4 digit value appears first, the format is YYYY/MM/DD, regardless of OS settings
- return makeDate(f0, f1, f2);
- }
- // otherwise the format seems to depend on OS settings (default date format)
- if (false) {
- // MM/DD/YYYY is probably a good guess, if the in the US
- return makeDate(f2, f0, f1);
- }
- // TODO - find a way to choose the correct date format
- throw new RuntimeException("Unable to determine date format for text '" + strVal + "'");
- }
-
- /**
- * @param month 1-based
- */
- private static Calendar makeDate(int year, int month, int day) throws EvaluationException {
- if (month < 1 || month > 12) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- Calendar cal = new GregorianCalendar(year, month-1, 1, 0, 0, 0);
- cal.set(Calendar.MILLISECOND, 0);
- if (day <1 || day>cal.getActualMaximum(Calendar.DAY_OF_MONTH)) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- cal.set(Calendar.DAY_OF_MONTH, day);
- return cal;
- }
-
- private static int evaluateIntArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol);
- return OperandResolver.coerceValueToInt(ve);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/atp/YearFracCalculator.java b/src/java/org/apache/poi/hssf/record/formula/atp/YearFracCalculator.java
deleted file mode 100644
index 9475db1bc6..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/atp/YearFracCalculator.java
+++ /dev/null
@@ -1,344 +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.atp;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.TimeZone;
-
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.EvaluationException;
-import org.apache.poi.ss.usermodel.DateUtil;
-
-
-/**
- * Internal calculation methods for Excel 'Analysis ToolPak' function YEARFRAC()
- * Value Days per Month Days per Year
- * 0 (default) 30 360
- * 1 actual actual
- * 2 actual 360
- * 3 actual 365
- * 4 30 360
- *
- * Algorithm inspired by www.dwheeler.com/yearfrac
- *
- * @author Josh Micich
- */
-final class YearFracCalculator {
- /** use UTC time-zone to avoid daylight savings issues */
- private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC");
- private static final int MS_PER_HOUR = 60 * 60 * 1000;
- private static final int MS_PER_DAY = 24 * MS_PER_HOUR;
- private static final int DAYS_PER_NORMAL_YEAR = 365;
- private static final int DAYS_PER_LEAP_YEAR = DAYS_PER_NORMAL_YEAR + 1;
-
- /** the length of normal long months i.e. 31 */
- private static final int LONG_MONTH_LEN = 31;
- /** the length of normal short months i.e. 30 */
- private static final int SHORT_MONTH_LEN = 30;
- private static final int SHORT_FEB_LEN = 28;
- private static final int LONG_FEB_LEN = SHORT_FEB_LEN + 1;
-
- private YearFracCalculator() {
- // no instances of this class
- }
-
-
- public static double calculate(double pStartDateVal, double pEndDateVal, int basis) throws EvaluationException {
-
- if (basis < 0 || basis >= 5) {
- // if basis is invalid the result is #NUM!
- throw new EvaluationException(ErrorEval.NUM_ERROR);
- }
-
- // common logic for all bases
-
- // truncate day values
- int startDateVal = (int) Math.floor(pStartDateVal);
- int endDateVal = (int) Math.floor(pEndDateVal);
- if (startDateVal == endDateVal) {
- // when dates are equal, result is zero
- return 0;
- }
- // swap start and end if out of order
- if (startDateVal > endDateVal) {
- int temp = startDateVal;
- startDateVal = endDateVal;
- endDateVal = temp;
- }
-
- switch (basis) {
- case 0: return basis0(startDateVal, endDateVal);
- case 1: return basis1(startDateVal, endDateVal);
- case 2: return basis2(startDateVal, endDateVal);
- case 3: return basis3(startDateVal, endDateVal);
- case 4: return basis4(startDateVal, endDateVal);
- }
- throw new IllegalStateException("cannot happen");
- }
-
-
- /**
- * @param startDateVal assumed to be less than or equal to endDateVal
- * @param endDateVal assumed to be greater than or equal to startDateVal
- */
- public static double basis0(int startDateVal, int endDateVal) {
- SimpleDate startDate = createDate(startDateVal);
- SimpleDate endDate = createDate(endDateVal);
- int date1day = startDate.day;
- int date2day = endDate.day;
-
- // basis zero has funny adjustments to the day-of-month fields when at end-of-month
- if (date1day == LONG_MONTH_LEN && date2day == LONG_MONTH_LEN) {
- date1day = SHORT_MONTH_LEN;
- date2day = SHORT_MONTH_LEN;
- } else if (date1day == LONG_MONTH_LEN) {
- date1day = SHORT_MONTH_LEN;
- } else if (date1day == SHORT_MONTH_LEN && date2day == LONG_MONTH_LEN) {
- date2day = SHORT_MONTH_LEN;
- // Note: If date2day==31, it STAYS 31 if date1day < 30.
- // Special fixes for February:
- } else if (startDate.month == 2 && isLastDayOfMonth(startDate)) {
- // Note - these assignments deliberately set Feb 30 date.
- date1day = SHORT_MONTH_LEN;
- if (endDate.month == 2 && isLastDayOfMonth(endDate)) {
- // only adjusted when first date is last day in Feb
- date2day = SHORT_MONTH_LEN;
- }
- }
- return calculateAdjusted(startDate, endDate, date1day, date2day);
- }
- /**
- * @param startDateVal assumed to be less than or equal to endDateVal
- * @param endDateVal assumed to be greater than or equal to startDateVal
- */
- public static double basis1(int startDateVal, int endDateVal) {
- SimpleDate startDate = createDate(startDateVal);
- SimpleDate endDate = createDate(endDateVal);
- double yearLength;
- if (isGreaterThanOneYear(startDate, endDate)) {
- yearLength = averageYearLength(startDate.year, endDate.year);
- } else if (shouldCountFeb29(startDate, endDate)) {
- yearLength = DAYS_PER_LEAP_YEAR;
- } else {
- yearLength = DAYS_PER_NORMAL_YEAR;
- }
- return dateDiff(startDate.tsMilliseconds, endDate.tsMilliseconds) / yearLength;
- }
-
- /**
- * @param startDateVal assumed to be less than or equal to endDateVal
- * @param endDateVal assumed to be greater than or equal to startDateVal
- */
- public static double basis2(int startDateVal, int endDateVal) {
- return (endDateVal - startDateVal) / 360.0;
- }
- /**
- * @param startDateVal assumed to be less than or equal to endDateVal
- * @param endDateVal assumed to be greater than or equal to startDateVal
- */
- public static double basis3(double startDateVal, double endDateVal) {
- return (endDateVal - startDateVal) / 365.0;
- }
- /**
- * @param startDateVal assumed to be less than or equal to endDateVal
- * @param endDateVal assumed to be greater than or equal to startDateVal
- */
- public static double basis4(int startDateVal, int endDateVal) {
- SimpleDate startDate = createDate(startDateVal);
- SimpleDate endDate = createDate(endDateVal);
- int date1day = startDate.day;
- int date2day = endDate.day;
-
-
- // basis four has funny adjustments to the day-of-month fields when at end-of-month
- if (date1day == LONG_MONTH_LEN) {
- date1day = SHORT_MONTH_LEN;
- }
- if (date2day == LONG_MONTH_LEN) {
- date2day = SHORT_MONTH_LEN;
- }
- // Note - no adjustments for end of Feb
- return calculateAdjusted(startDate, endDate, date1day, date2day);
- }
-
-
- private static double calculateAdjusted(SimpleDate startDate, SimpleDate endDate, int date1day,
- int date2day) {
- double dayCount
- = (endDate.year - startDate.year) * 360
- + (endDate.month - startDate.month) * SHORT_MONTH_LEN
- + (date2day - date1day) * 1;
- return dayCount / 360;
- }
-
- private static boolean isLastDayOfMonth(SimpleDate date) {
- if (date.day < SHORT_FEB_LEN) {
- return false;
- }
- return date.day == getLastDayOfMonth(date);
- }
-
- private static int getLastDayOfMonth(SimpleDate date) {
- switch (date.month) {
- case 1:
- case 3:
- case 5:
- case 7:
- case 8:
- case 10:
- case 12:
- return LONG_MONTH_LEN;
- case 4:
- case 6:
- case 9:
- case 11:
- return SHORT_MONTH_LEN;
- }
- if (isLeapYear(date.year)) {
- return LONG_FEB_LEN;
- }
- return SHORT_FEB_LEN;
- }
-
- /**
- * Assumes dates are no more than 1 year apart.
- * @return true
if dates both within a leap year, or span a period including Feb 29
- */
- private static boolean shouldCountFeb29(SimpleDate start, SimpleDate end) {
- boolean startIsLeapYear = isLeapYear(start.year);
- if (startIsLeapYear && start.year == end.year) {
- // note - dates may not actually span Feb-29, but it gets counted anyway in this case
- return true;
- }
-
- boolean endIsLeapYear = isLeapYear(end.year);
- if (!startIsLeapYear && !endIsLeapYear) {
- return false;
- }
- if (startIsLeapYear) {
- switch (start.month) {
- case SimpleDate.JANUARY:
- case SimpleDate.FEBRUARY:
- return true;
- }
- return false;
- }
- if (endIsLeapYear) {
- switch (end.month) {
- case SimpleDate.JANUARY:
- return false;
- case SimpleDate.FEBRUARY:
- break;
- default:
- return true;
- }
- return end.day == LONG_FEB_LEN;
- }
- return false;
- }
-
- /**
- * @return the whole number of days between the two time-stamps. Both time-stamps are
- * assumed to represent 12:00 midnight on the respective day.
- */
- private static int dateDiff(long startDateMS, long endDateMS) {
- long msDiff = endDateMS - startDateMS;
-
- // some extra checks to make sure we don't hide some other bug with the rounding
- int remainderHours = (int) ((msDiff % MS_PER_DAY) / MS_PER_HOUR);
- switch (remainderHours) {
- case 0: // normal case
- break;
- case 1: // transition from normal time to daylight savings adjusted
- case 23: // transition from daylight savings adjusted to normal time
- // Unexpected since we are using UTC_TIME_ZONE
- default:
- throw new RuntimeException("Unexpected date diff between " + startDateMS + " and " + endDateMS);
-
- }
- return (int) (0.5 + ((double)msDiff / MS_PER_DAY));
- }
-
- private static double averageYearLength(int startYear, int endYear) {
- int dayCount = 0;
- for (int i=startYear; i<=endYear; i++) {
- dayCount += DAYS_PER_NORMAL_YEAR;
- if (isLeapYear(i)) {
- dayCount++;
- }
- }
- double numberOfYears = endYear-startYear+1;
- return dayCount / numberOfYears;
- }
-
- private static boolean isLeapYear(int i) {
- // leap years are always divisible by 4
- if (i % 4 != 0) {
- return false;
- }
- // each 4th century is a leap year
- if (i % 400 == 0) {
- return true;
- }
- // all other centuries are *not* leap years
- if (i % 100 == 0) {
- return false;
- }
- return true;
- }
-
- private static boolean isGreaterThanOneYear(SimpleDate start, SimpleDate end) {
- if (start.year == end.year) {
- return false;
- }
- if (start.year + 1 != end.year) {
- return true;
- }
-
- if (start.month > end.month) {
- return false;
- }
- if (start.month < end.month) {
- return true;
- }
-
- return start.day < end.day;
- }
-
- private static SimpleDate createDate(int dayCount) {
- GregorianCalendar calendar = new GregorianCalendar(UTC_TIME_ZONE);
- DateUtil.setCalendar(calendar, dayCount, 0, false);
- return new SimpleDate(calendar);
- }
-
- private static final class SimpleDate {
-
- public static final int JANUARY = 1;
- public static final int FEBRUARY = 2;
-
- public final int year;
- /** 1-based month */
- public final int month;
- /** day of month */
- public final int day;
- /** milliseconds since 1970 */
- public long tsMilliseconds;
-
- public SimpleDate(Calendar cal) {
- year = cal.get(Calendar.YEAR);
- month = cal.get(Calendar.MONTH) + 1;
- day = cal.get(Calendar.DAY_OF_MONTH);
- tsMilliseconds = cal.getTimeInMillis();
- }
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java
deleted file mode 100644
index 733a6253e4..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java
+++ /dev/null
@@ -1,93 +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.eval;
-
-import org.apache.poi.ss.formula.TwoDEval;
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public interface AreaEval extends TwoDEval {
-
- /**
- * returns the 0-based index of the first row in
- * this area.
- */
- int getFirstRow();
-
- /**
- * returns the 0-based index of the last row in
- * this area.
- */
- int getLastRow();
-
- /**
- * returns the 0-based index of the first col in
- * this area.
- */
- int getFirstColumn();
-
- /**
- * returns the 0-based index of the last col in
- * this area.
- */
- int getLastColumn();
-
- /**
- * @return the ValueEval from within this area at the specified row and col index. Never
- * null
(possibly {@link BlankEval}). The specified indexes should be absolute
- * indexes in the sheet and not relative indexes within the area.
- */
- ValueEval getAbsoluteValue(int row, int col);
-
- /**
- * returns true if the cell at row and col specified
- * as absolute indexes in the sheet is contained in
- * this area.
- * @param row
- * @param col
- */
- boolean contains(int row, int col);
-
- /**
- * returns true if the specified col is in range
- * @param col
- */
- boolean containsColumn(int col);
-
- /**
- * returns true if the specified row is in range
- * @param row
- */
- boolean containsRow(int row);
-
- int getWidth();
- int getHeight();
- /**
- * @return the ValueEval from within this area at the specified relativeRowIndex and
- * relativeColumnIndex. Never null
(possibly {@link BlankEval}). The
- * specified indexes should relative to the top left corner of this area.
- */
- ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
-
- /**
- * Creates an {@link AreaEval} offset by a relative amount from from the upper left cell
- * of this area
- */
- AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java
deleted file mode 100644
index 4d04fd126f..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/AreaEvalBase.java
+++ /dev/null
@@ -1,117 +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.eval;
-
-import org.apache.poi.hssf.record.formula.AreaI;
-
-/**
- * @author Josh Micich
- */
-public abstract class AreaEvalBase implements AreaEval {
-
- private final int _firstColumn;
- private final int _firstRow;
- private final int _lastColumn;
- private final int _lastRow;
- private final int _nColumns;
- private final int _nRows;
-
- protected AreaEvalBase(int firstRow, int firstColumn, int lastRow, int lastColumn) {
- _firstColumn = firstColumn;
- _firstRow = firstRow;
- _lastColumn = lastColumn;
- _lastRow = lastRow;
-
- _nColumns = _lastColumn - _firstColumn + 1;
- _nRows = _lastRow - _firstRow + 1;
- }
-
- protected AreaEvalBase(AreaI ptg) {
- _firstRow = ptg.getFirstRow();
- _firstColumn = ptg.getFirstColumn();
- _lastRow = ptg.getLastRow();
- _lastColumn = ptg.getLastColumn();
-
- _nColumns = _lastColumn - _firstColumn + 1;
- _nRows = _lastRow - _firstRow + 1;
- }
-
- public final int getFirstColumn() {
- return _firstColumn;
- }
-
- public final int getFirstRow() {
- return _firstRow;
- }
-
- public final int getLastColumn() {
- return _lastColumn;
- }
-
- public final int getLastRow() {
- return _lastRow;
- }
- public final ValueEval getAbsoluteValue(int row, int col) {
- int rowOffsetIx = row - _firstRow;
- int colOffsetIx = col - _firstColumn;
-
- if(rowOffsetIx < 0 || rowOffsetIx >= _nRows) {
- throw new IllegalArgumentException("Specified row index (" + row
- + ") is outside the allowed range (" + _firstRow + ".." + _lastRow + ")");
- }
- if(colOffsetIx < 0 || colOffsetIx >= _nColumns) {
- throw new IllegalArgumentException("Specified column index (" + col
- + ") is outside the allowed range (" + _firstColumn + ".." + col + ")");
- }
- return getRelativeValue(rowOffsetIx, colOffsetIx);
- }
-
- public final boolean contains(int row, int col) {
- return _firstRow <= row && _lastRow >= row
- && _firstColumn <= col && _lastColumn >= col;
- }
-
- public final boolean containsRow(int row) {
- return _firstRow <= row && _lastRow >= row;
- }
-
- public final boolean containsColumn(int col) {
- return _firstColumn <= col && _lastColumn >= col;
- }
-
- public final boolean isColumn() {
- return _firstColumn == _lastColumn;
- }
-
- public final boolean isRow() {
- return _firstRow == _lastRow;
- }
- public int getHeight() {
- return _lastRow-_firstRow+1;
- }
-
- public final ValueEval getValue(int row, int col) {
- return getRelativeValue(row, col);
- }
-
- public abstract ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex);
-
- public int getWidth() {
- return _lastColumn-_firstColumn+1;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/BlankEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/BlankEval.java
deleted file mode 100644
index 3e5147122d..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/BlankEval.java
+++ /dev/null
@@ -1,35 +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.eval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com > This class is a
- * marker class. It is a special value for empty cells.
- */
-public final class BlankEval implements ValueEval {
-
- public static final BlankEval instance = new BlankEval();
- /**
- * @deprecated (Nov 2009) use {@link #instance}
- */
- public static final BlankEval INSTANCE = instance;
-
- private BlankEval() {
- // enforce singleton
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/BoolEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/BoolEval.java
deleted file mode 100644
index 6ca60899ad..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/BoolEval.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.eval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public final class BoolEval implements NumericValueEval, StringValueEval {
-
- private boolean _value;
-
- public static final BoolEval FALSE = new BoolEval(false);
-
- public static final BoolEval TRUE = new BoolEval(true);
-
- /**
- * Convenience method for the following:
- * (b ? BoolEval.TRUE : BoolEval.FALSE)
- *
- * @return the BoolEval instance representing b.
- */
- public static final BoolEval valueOf(boolean b) {
- return b ? TRUE : FALSE;
- }
-
- private BoolEval(boolean value) {
- _value = value;
- }
-
- public boolean getBooleanValue() {
- return _value;
- }
-
- public double getNumberValue() {
- return _value ? 1 : 0;
- }
-
- public String getStringValue() {
- return _value ? "TRUE" : "FALSE";
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(getStringValue());
- sb.append("]");
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java
deleted file mode 100644
index f52aea98f1..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java
+++ /dev/null
@@ -1,60 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public final class ConcatEval extends Fixed2ArgFunction {
-
- public static final Function instance = new ConcatEval();
-
- private ConcatEval() {
- // enforce singleton
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
- ValueEval ve0;
- ValueEval ve1;
- try {
- ve0 = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- StringBuilder sb = new StringBuilder();
- sb.append(getText(ve0));
- sb.append(getText(ve1));
- return new StringEval(sb.toString());
- }
-
- private Object getText(ValueEval ve) {
- if (ve instanceof StringValueEval) {
- StringValueEval sve = (StringValueEval) ve;
- return sve.getStringValue();
- }
- if (ve == BlankEval.instance) {
- return "";
- }
- throw new IllegalAccessError("Unexpected value type ("
- + ve.getClass().getName() + ")");
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java
deleted file mode 100644
index 13f51f5f80..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java
+++ /dev/null
@@ -1,111 +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.eval;
-
-import org.apache.poi.ss.usermodel.ErrorConstants;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public final class ErrorEval implements ValueEval {
-
- // convenient access to namespace
- private static final ErrorConstants EC = null;
-
- /** #NULL! - Intersection of two cell ranges is empty */
- public static final ErrorEval NULL_INTERSECTION = new ErrorEval(EC.ERROR_NULL);
- /** #DIV/0! - Division by zero */
- public static final ErrorEval DIV_ZERO = new ErrorEval(EC.ERROR_DIV_0);
- /** #VALUE! - Wrong type of operand */
- public static final ErrorEval VALUE_INVALID = new ErrorEval(EC.ERROR_VALUE);
- /** #REF! - Illegal or deleted cell reference */
- public static final ErrorEval REF_INVALID = new ErrorEval(EC.ERROR_REF);
- /** #NAME? - Wrong function or range name */
- public static final ErrorEval NAME_INVALID = new ErrorEval(EC.ERROR_NAME);
- /** #NUM! - Value range overflow */
- public static final ErrorEval NUM_ERROR = new ErrorEval(EC.ERROR_NUM);
- /** #N/A - Argument or function not available */
- public static final ErrorEval NA = new ErrorEval(EC.ERROR_NA);
-
-
- // POI internal error codes
- private static final int CIRCULAR_REF_ERROR_CODE = 0xFFFFFFC4;
- private static final int FUNCTION_NOT_IMPLEMENTED_CODE = 0xFFFFFFE2;
-
- // Note - Excel does not seem to represent this condition with an error code
- public static final ErrorEval CIRCULAR_REF_ERROR = new ErrorEval(CIRCULAR_REF_ERROR_CODE);
-
-
- /**
- * Translates an Excel internal error code into the corresponding POI ErrorEval instance
- * @param errorCode
- */
- public static ErrorEval valueOf(int errorCode) {
- switch(errorCode) {
- case ErrorConstants.ERROR_NULL: return NULL_INTERSECTION;
- case ErrorConstants.ERROR_DIV_0: return DIV_ZERO;
- case ErrorConstants.ERROR_VALUE: return VALUE_INVALID;
- case ErrorConstants.ERROR_REF: return REF_INVALID;
- case ErrorConstants.ERROR_NAME: return NAME_INVALID;
- case ErrorConstants.ERROR_NUM: return NUM_ERROR;
- case ErrorConstants.ERROR_NA: return NA;
- // non-std errors (conditions modeled as errors by POI)
- case CIRCULAR_REF_ERROR_CODE: return CIRCULAR_REF_ERROR;
- }
- throw new RuntimeException("Unexpected error code (" + errorCode + ")");
- }
-
- /**
- * Converts error codes to text. Handles non-standard error codes OK.
- * For debug/test purposes (and for formatting error messages).
- * @return the String representation of the specified Excel error code.
- */
- public static String getText(int errorCode) {
- if(ErrorConstants.isValidCode(errorCode)) {
- return ErrorConstants.getText(errorCode);
- }
- // It is desirable to make these (arbitrary) strings look clearly different from any other
- // value expression that might appear in a formula. In addition these error strings should
- // look unlike the standard Excel errors. Hence tilde ('~') was used.
- switch(errorCode) {
- case CIRCULAR_REF_ERROR_CODE: return "~CIRCULAR~REF~";
- case FUNCTION_NOT_IMPLEMENTED_CODE: return "~FUNCTION~NOT~IMPLEMENTED~";
- }
- return "~non~std~err(" + errorCode + ")~";
- }
-
- private int _errorCode;
- /**
- * @param errorCode an 8-bit value
- */
- private ErrorEval(int errorCode) {
- _errorCode = errorCode;
- }
-
- public int getErrorCode() {
- return _errorCode;
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(getText(_errorCode));
- sb.append("]");
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/EvaluationException.java b/src/java/org/apache/poi/hssf/record/formula/eval/EvaluationException.java
deleted file mode 100644
index 7a23901b25..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/EvaluationException.java
+++ /dev/null
@@ -1,134 +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.eval;
-
-/**
- * This class is used to simplify error handling logic within operator and function
- * implementations. Note - OperationEval.evaluate() and Function.evaluate()
- * method signatures do not throw this exception so it cannot propagate outside.
- *
- * Here is an example coded without EvaluationException, to show how it can help:
- *
- * public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- * // ...
- * Eval arg0 = args[0];
- * if(arg0 instanceof ErrorEval) {
- * return arg0;
- * }
- * if(!(arg0 instanceof AreaEval)) {
- * return ErrorEval.VALUE_INVALID;
- * }
- * double temp = 0;
- * AreaEval area = (AreaEval)arg0;
- * ValueEval[] values = area.getValues();
- * for (int i = 0; i < values.length; i++) {
- * ValueEval ve = values[i];
- * if(ve instanceof ErrorEval) {
- * return ve;
- * }
- * if(!(ve instanceof NumericValueEval)) {
- * return ErrorEval.VALUE_INVALID;
- * }
- * temp += ((NumericValueEval)ve).getNumberValue();
- * }
- * // ...
- * }
- *
- * In this example, if any error is encountered while processing the arguments, an error is
- * returned immediately. This code is difficult to refactor due to all the points where errors
- * are returned.
- * Using EvaluationException allows the error returning code to be consolidated to one
- * place.
- *
- * public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
- * try {
- * // ...
- * AreaEval area = getAreaArg(args[0]);
- * double temp = sumValues(area.getValues());
- * // ...
- * } catch (EvaluationException e) {
- * return e.getErrorEval();
- * }
- *}
- *
- *private static AreaEval getAreaArg(Eval arg0) throws EvaluationException {
- * if (arg0 instanceof ErrorEval) {
- * throw new EvaluationException((ErrorEval) arg0);
- * }
- * if (arg0 instanceof AreaEval) {
- * return (AreaEval) arg0;
- * }
- * throw EvaluationException.invalidValue();
- *}
- *
- *private double sumValues(ValueEval[] values) throws EvaluationException {
- * double temp = 0;
- * for (int i = 0; i < values.length; i++) {
- * ValueEval ve = values[i];
- * if (ve instanceof ErrorEval) {
- * throw new EvaluationException((ErrorEval) ve);
- * }
- * if (!(ve instanceof NumericValueEval)) {
- * throw EvaluationException.invalidValue();
- * }
- * temp += ((NumericValueEval) ve).getNumberValue();
- * }
- * return temp;
- *}
- *
- * It is not mandatory to use EvaluationException, doing so might give the following advantages:
- * - Methods can more easily be extracted, allowing for re-use.
- * - Type management (typecasting etc) is simpler because error conditions have been separated from
- * intermediate calculation values.
- * - Fewer local variables are required. Local variables can have stronger types.
- * - It is easier to mimic common Excel error handling behaviour (exit upon encountering first
- * error), because exceptions conveniently propagate up the call stack regardless of execution
- * points or the number of levels of nested calls.
- *
- * Note - Only standard evaluation errors are represented by EvaluationException (
- * i.e. conditions expected to be encountered when evaluating arbitrary Excel formulas). Conditions
- * that could never occur in an Excel spreadsheet should result in runtime exceptions. Care should
- * be taken to not translate any POI internal error into an Excel evaluation error code.
- *
- * @author Josh Micich
- */
-public final class EvaluationException extends Exception {
- private final ErrorEval _errorEval;
-
- public EvaluationException(ErrorEval errorEval) {
- _errorEval = errorEval;
- }
- // some convenience factory methods
-
- /** #VALUE! - Wrong type of operand */
- public static EvaluationException invalidValue() {
- return new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- /** #REF! - Illegal or deleted cell reference */
- public static EvaluationException invalidRef() {
- return new EvaluationException(ErrorEval.REF_INVALID);
- }
- /** #NUM! - Value range overflow */
- public static EvaluationException numberError() {
- return new EvaluationException(ErrorEval.NUM_ERROR);
- }
-
- public ErrorEval getErrorEval() {
- return _errorEval;
- }
-}
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
deleted file mode 100644
index d7be348650..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java
+++ /dev/null
@@ -1,250 +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.eval;
-
-import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
-import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
-import org.apache.poi.hssf.record.formula.functions.*;
-import org.apache.poi.ss.formula.eval.NotImplementedException;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public final class FunctionEval {
- /**
- * Some function IDs that require special treatment
- */
- private static final class FunctionID {
- /** 1 */
- public static final int IF = FunctionMetadataRegistry.FUNCTION_INDEX_IF;
- /** 4 */
- public static final int SUM = FunctionMetadataRegistry.FUNCTION_INDEX_SUM;
- /** 78 */
- public static final int OFFSET = 78;
- /** 100 */
- public static final int CHOOSE = FunctionMetadataRegistry.FUNCTION_INDEX_CHOOSE;
- /** 148 */
- public static final int INDIRECT = FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT;
- /** 255 */
- public static final int EXTERNAL_FUNC = FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL;
- }
- // convenient access to namespace
- private static final FunctionID ID = null;
-
- /**
- * Array elements corresponding to unimplemented functions are null
- */
- protected static final Function[] functions = produceFunctions();
-
- private static Function[] produceFunctions() {
- Function[] retval = new Function[368];
-
- retval[0] = new Count();
- retval[ID.IF] = new IfFunc();
- retval[2] = LogicalFunction.ISNA;
- retval[3] = LogicalFunction.ISERROR;
- retval[ID.SUM] = AggregateFunction.SUM;
- retval[5] = AggregateFunction.AVERAGE;
- retval[6] = AggregateFunction.MIN;
- retval[7] = AggregateFunction.MAX;
- retval[8] = new RowFunc(); // ROW
- retval[9] = new Column();
- retval[10] = new Na();
- retval[11] = new Npv();
- retval[12] = AggregateFunction.STDEV;
- retval[13] = NumericFunction.DOLLAR;
-
- retval[15] = NumericFunction.SIN;
- retval[16] = NumericFunction.COS;
- retval[17] = NumericFunction.TAN;
- retval[18] = NumericFunction.ATAN;
- retval[19] = NumericFunction.PI;
- retval[20] = NumericFunction.SQRT;
- retval[21] = NumericFunction.EXP;
- retval[22] = NumericFunction.LN;
- retval[23] = NumericFunction.LOG10;
- retval[24] = NumericFunction.ABS;
- retval[25] = NumericFunction.INT;
- retval[26] = NumericFunction.SIGN;
- retval[27] = NumericFunction.ROUND;
- retval[28] = new Lookup();
- retval[29] = new Index();
-
- retval[31] = TextFunction.MID;
- retval[32] = TextFunction.LEN;
- retval[33] = new Value();
- retval[34] = BooleanFunction.TRUE;
- retval[35] = BooleanFunction.FALSE;
- retval[36] = BooleanFunction.AND;
- retval[37] = BooleanFunction.OR;
- retval[38] = BooleanFunction.NOT;
- retval[39] = NumericFunction.MOD;
- retval[48] = TextFunction.TEXT;
-
- retval[56] = FinanceFunction.PV;
- retval[57] = FinanceFunction.FV;
- retval[58] = FinanceFunction.NPER;
- retval[59] = FinanceFunction.PMT;
-
- retval[63] = NumericFunction.RAND;
- retval[64] = new Match();
- retval[65] = DateFunc.instance;
- retval[66] = new TimeFunc();
- retval[67] = CalendarFieldFunction.DAY;
- retval[68] = CalendarFieldFunction.MONTH;
- retval[69] = CalendarFieldFunction.YEAR;
-
- retval[74] = new Now();
-
- retval[76] = new Rows();
- retval[77] = new Columns();
- retval[82] = TextFunction.SEARCH;
- retval[ID.OFFSET] = new Offset();
- retval[82] = TextFunction.SEARCH;
-
- retval[97] = NumericFunction.ATAN2;
- retval[98] = NumericFunction.ASIN;
- retval[99] = NumericFunction.ACOS;
- retval[ID.CHOOSE] = new Choose();
- retval[101] = new Hlookup();
- retval[102] = new Vlookup();
-
- retval[105] = LogicalFunction.ISREF;
-
- retval[109] = NumericFunction.LOG;
-
- retval[112] = TextFunction.LOWER;
- retval[113] = TextFunction.UPPER;
-
- retval[115] = TextFunction.LEFT;
- retval[116] = TextFunction.RIGHT;
- retval[117] = TextFunction.EXACT;
- retval[118] = TextFunction.TRIM;
- retval[119] = new Replace();
- retval[120] = new Substitute();
-
- retval[124] = TextFunction.FIND;
-
- retval[127] = LogicalFunction.ISTEXT;
- retval[128] = LogicalFunction.ISNUMBER;
- retval[129] = LogicalFunction.ISBLANK;
- retval[130] = new T();
-
- retval[ID.INDIRECT] = null; // Indirect.evaluate has different signature
-
- retval[169] = new Counta();
-
- retval[183] = AggregateFunction.PRODUCT;
- retval[184] = NumericFunction.FACT;
-
- retval[190] = LogicalFunction.ISNONTEXT;
- retval[197] = NumericFunction.TRUNC;
- retval[198] = LogicalFunction.ISLOGICAL;
-
- retval[212] = NumericFunction.ROUNDUP;
- retval[213] = NumericFunction.ROUNDDOWN;
-
- retval[220] = new Days360();
- retval[221] = new Today();
-
- retval[227] = AggregateFunction.MEDIAN;
- retval[228] = new Sumproduct();
- retval[229] = NumericFunction.SINH;
- retval[230] = NumericFunction.COSH;
- retval[231] = NumericFunction.TANH;
- retval[232] = NumericFunction.ASINH;
- retval[233] = NumericFunction.ACOSH;
- retval[234] = NumericFunction.ATANH;
-
- retval[ID.EXTERNAL_FUNC] = null; // ExternalFunction is a FreeREfFunction
-
- retval[261] = new Errortype();
-
- retval[269] = AggregateFunction.AVEDEV;
-
- retval[276] = NumericFunction.COMBIN;
-
- retval[279] = new Even();
-
- retval[285] = NumericFunction.FLOOR;
-
- retval[288] = NumericFunction.CEILING;
-
- retval[298] = new Odd();
-
- retval[300] = NumericFunction.POISSON;
-
- retval[303] = new Sumxmy2();
- retval[304] = new Sumx2my2();
- retval[305] = new Sumx2py2();
-
- retval[318] = AggregateFunction.DEVSQ;
-
- retval[321] = AggregateFunction.SUMSQ;
-
- retval[325] = AggregateFunction.LARGE;
- retval[326] = AggregateFunction.SMALL;
-
- retval[330] = new Mode();
-
- retval[336] = TextFunction.CONCATENATE;
- retval[337] = NumericFunction.POWER;
-
- retval[342] = NumericFunction.RADIANS;
- retval[343] = NumericFunction.DEGREES;
-
- retval[344] = new Subtotal();
- retval[345] = new Sumif();
- retval[346] = new Countif();
- retval[347] = new Countblank();
-
- retval[359] = new Hyperlink();
-
- retval[362] = MinaMaxa.MAXA;
- retval[363] = MinaMaxa.MINA;
-
- for (int i = 0; i < retval.length; i++) {
- Function f = retval[i];
- if (f == null) {
- FunctionMetadata fm = FunctionMetadataRegistry.getFunctionByIndex(i);
- if (fm == null) {
- continue;
- }
- retval[i] = new NotImplementedFunction(fm.getName());
- }
- }
- return retval;
- }
- /**
- * @return null
if the specified functionIndex is for INDIRECT() or any external (add-in) function.
- */
- public static Function getBasicFunction(int functionIndex) {
- // check for 'free ref' functions first
- switch (functionIndex) {
- case FunctionID.INDIRECT:
- case FunctionID.EXTERNAL_FUNC:
- return null;
- }
- // else - must be plain function
- Function result = functions[functionIndex];
- if (result == null) {
- throw new NotImplementedException("FuncIx=" + functionIndex);
- }
- return result;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/IntersectionEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/IntersectionEval.java
deleted file mode 100644
index e30df36f59..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/IntersectionEval.java
+++ /dev/null
@@ -1,96 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-
-/**
- * @author Josh Micich
- */
-public final class IntersectionEval extends Fixed2ArgFunction {
-
- public static final Function instance = new IntersectionEval();
-
- private IntersectionEval() {
- // enforces singleton
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
-
- try {
- AreaEval reA = evaluateRef(arg0);
- AreaEval reB = evaluateRef(arg1);
- AreaEval result = resolveRange(reA, reB);
- if (result == null) {
- return ErrorEval.NULL_INTERSECTION;
- }
- return result;
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- }
-
- /**
- * @return simple rectangular {@link AreaEval} which represents the intersection of areas
- * aeA and aeB. If the two areas do not intersect, the result is null
.
- */
- private static AreaEval resolveRange(AreaEval aeA, AreaEval aeB) {
-
- int aeAfr = aeA.getFirstRow();
- int aeAfc = aeA.getFirstColumn();
- int aeBlc = aeB.getLastColumn();
- if (aeAfc > aeBlc) {
- return null;
- }
- int aeBfc = aeB.getFirstColumn();
- if (aeBfc > aeA.getLastColumn()) {
- return null;
- }
- int aeBlr = aeB.getLastRow();
- if (aeAfr > aeBlr) {
- return null;
- }
- int aeBfr = aeB.getFirstRow();
- int aeAlr = aeA.getLastRow();
- if (aeBfr > aeAlr) {
- return null;
- }
-
-
- int top = Math.max(aeAfr, aeBfr);
- int bottom = Math.min(aeAlr, aeBlr);
- int left = Math.max(aeAfc, aeBfc);
- int right = Math.min(aeA.getLastColumn(), aeBlc);
-
- return aeA.offset(top-aeAfr, bottom-aeAfr, left-aeAfc, right-aeAfc);
- }
-
- private static AreaEval evaluateRef(ValueEval arg) throws EvaluationException {
- if (arg instanceof AreaEval) {
- return (AreaEval) arg;
- }
- if (arg instanceof RefEval) {
- return ((RefEval) arg).offset(0, 0, 0, 0);
- }
- if (arg instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval)arg);
- }
- throw new IllegalArgumentException("Unexpected ref arg class (" + arg.getClass().getName() + ")");
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java
deleted file mode 100644
index 984e6383ab..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java
+++ /dev/null
@@ -1,36 +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.eval;
-
-/**
- * Represents the (intermediate) evaluated result of a missing function argument. In most cases
- * this can be translated into {@link BlankEval} but there are some notable exceptions. Functions
- * COUNT and COUNTA do count their missing args. Note - the differences between
- * {@link MissingArgEval} and {@link BlankEval} have not been investigated fully, so the POI
- * evaluator may need to be updated to account for these as they are found.
- *
- * @author Josh Micich
- */
-public final class MissingArgEval implements ValueEval {
-
- public static final MissingArgEval instance = new MissingArgEval();
-
- private MissingArgEval() {
- // enforce singleton
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/NameEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/NameEval.java
deleted file mode 100644
index 9b5e21b184..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/NameEval.java
+++ /dev/null
@@ -1,46 +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.eval;
-
-/**
- * @author Josh Micich
- */
-public final class NameEval implements ValueEval {
-
- private final String _functionName;
-
- /**
- * Creates a NameEval representing a function name
- */
- public NameEval(String functionName) {
- _functionName = functionName;
- }
-
-
- public String getFunctionName() {
- return _functionName;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(_functionName);
- sb.append("]");
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/NameXEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/NameXEval.java
deleted file mode 100644
index d1b8ffef76..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/NameXEval.java
+++ /dev/null
@@ -1,44 +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.eval;
-
-import org.apache.poi.hssf.record.formula.NameXPtg;
-
-/**
- * @author Josh Micich
- */
-public final class NameXEval implements ValueEval {
-
- private final NameXPtg _ptg;
-
- public NameXEval(NameXPtg ptg) {
- _ptg = ptg;
- }
-
- public NameXPtg getPtg() {
- return _ptg;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(_ptg.getSheetRefIndex()).append(", ").append(_ptg.getNameIndex());
- sb.append("]");
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/NumberEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/NumberEval.java
deleted file mode 100644
index 33aff2a493..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/NumberEval.java
+++ /dev/null
@@ -1,73 +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 8, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.eval;
-
-import org.apache.poi.hssf.record.formula.IntPtg;
-import org.apache.poi.hssf.record.formula.NumberPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.ss.util.NumberToTextConverter;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public final class NumberEval implements NumericValueEval, StringValueEval {
-
- public static final NumberEval ZERO = new NumberEval(0);
-
- private final double _value;
- private String _stringValue;
-
- public NumberEval(Ptg ptg) {
- if (ptg == null) {
- throw new IllegalArgumentException("ptg must not be null");
- }
- if (ptg instanceof IntPtg) {
- _value = ((IntPtg) ptg).getValue();
- } else if (ptg instanceof NumberPtg) {
- _value = ((NumberPtg) ptg).getValue();
- } else {
- throw new IllegalArgumentException("bad argument type (" + ptg.getClass().getName() + ")");
- }
- }
-
- public NumberEval(double value) {
- _value = value;
- }
-
- public double getNumberValue() {
- return _value;
- }
-
- public String getStringValue() {
- if (_stringValue == null) {
- _stringValue = NumberToTextConverter.toText(_value);
- }
- return _stringValue;
- }
- public final String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(getStringValue());
- sb.append("]");
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java
deleted file mode 100644
index d5b92b8080..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java
+++ /dev/null
@@ -1,30 +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 8, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.eval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public interface NumericValueEval extends ValueEval {
-
- public abstract double getNumberValue();
-}
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
deleted file mode 100644
index f81ebdde0f..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java
+++ /dev/null
@@ -1,324 +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.eval;
-
-import java.util.regex.Pattern;
-
-/**
- * Provides functionality for evaluating arguments to functions and operators.
- *
- * @author Josh Micich
- * @author Brendan Nolan
- */
-public final class OperandResolver {
-
- // Based on regular expression defined in JavaDoc at {@link java.lang.Double#valueOf}
- // modified to remove support for NaN, Infinity, Hexadecimal support and floating type suffixes
- private static final String Digits = "(\\p{Digit}+)";
- private static final String Exp = "[eE][+-]?"+Digits;
- private static final String fpRegex =
- ("[\\x00-\\x20]*" +
- "[+-]?(" +
- "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+
- "(\\.("+Digits+")("+Exp+")?))))"+
- "[\\x00-\\x20]*");
-
-
- private OperandResolver() {
- // no instances of this class
- }
-
- /**
- * Retrieves a single value from a variety of different argument types according to standard
- * Excel rules. Does not perform any type conversion.
- * @param arg the evaluated argument as passed to the function or operator.
- * @param srcCellRow used when arg is a single column AreaRef
- * @param srcCellCol used when arg is a single row AreaRef
- * @return a NumberEval, StringEval, BoolEval or BlankEval.
- * Never null
or ErrorEval.
- * @throws EvaluationException(#VALUE!) if srcCellRow or srcCellCol do not properly index into
- * an AreaEval. If the actual value retrieved is an ErrorEval, a corresponding
- * EvaluationException is thrown.
- */
- public static ValueEval getSingleValue(ValueEval arg, int srcCellRow, int srcCellCol)
- throws EvaluationException {
- ValueEval result;
- if (arg instanceof RefEval) {
- result = ((RefEval) arg).getInnerValueEval();
- } else if (arg instanceof AreaEval) {
- result = chooseSingleElementFromArea((AreaEval) arg, srcCellRow, srcCellCol);
- } else {
- result = arg;
- }
- if (result instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) result);
- }
- return result;
- }
-
- /**
- * Implements (some perhaps not well known) Excel functionality to select a single cell from an
- * area depending on the coordinates of the calling cell. Here is an example demonstrating
- * both selection from a single row area and a single column area in the same formula.
- *
- *
- *
- *
- * If the formula "=1000+A1:B1+D2:D3" is put into the 9 cells from A2 to C4, the spreadsheet
- * will look like this:
- *
- *
- * A B C D
- * 1 15 20 25
- * 2 200
- * 3 300
- * 3 400
- *
- *
- * Note that the row area (A1:B1) does not include column C and the column area (D2:D3) does
- * not include row 4, so the values in C1(=25) and D4(=400) are not accessible to the formula
- * as written, but in the 4 cells A2:B3, the row and column selection works ok.
- *
- * The same concept is extended to references across sheets, such that even multi-row,
- * multi-column areas can be useful.
- *
- * Of course with carefully (or carelessly) chosen parameters, cyclic references can occur and
- * hence this method can throw a 'circular reference' EvaluationException. Note that
- * this method does not attempt to detect cycles. Every cell in the specified Area ae
- * has already been evaluated prior to this method call. Any cell (or cells) part of
- * ae that would incur a cyclic reference error if selected by this method, will
- * already have the value
- * A B C D
- * 1 15 20 25
- * 2 1215 1220 #VALUE! 200
- * 3 1315 1320 #VALUE! 300
- * 4 #VALUE! #VALUE! #VALUE! 400 null
. Never
- * ErrorEval.
- * @throws EvaluationException if there is a problem with indexing into the area, or if the
- * evaluated cell has an error.
- */
- public static ValueEval chooseSingleElementFromArea(AreaEval ae,
- int srcCellRow, int srcCellCol) throws EvaluationException {
- ValueEval result = chooseSingleElementFromAreaInternal(ae, srcCellRow, srcCellCol);
- if (result instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) result);
- }
- return result;
- }
-
- /**
- * @return possibly ErrorEval, and null
- */
- private static ValueEval chooseSingleElementFromAreaInternal(AreaEval ae,
- int srcCellRow, int srcCellCol) throws EvaluationException {
-
- if(false) {
- // this is too simplistic
- if(ae.containsRow(srcCellRow) && ae.containsColumn(srcCellCol)) {
- throw new EvaluationException(ErrorEval.CIRCULAR_REF_ERROR);
- }
- /*
- Circular references are not dealt with directly here, but it is worth noting some issues.
-
- ANY one of the return statements in this method could return a cell that is identical
- to the one immediately being evaluated. The evaluating cell is identified by srcCellRow,
- srcCellRow AND sheet. The sheet is not available in any nearby calling method, so that's
- one reason why circular references are not easy to detect here. (The sheet of the returned
- cell can be obtained from ae if it is an Area3DEval.)
-
- Another reason there's little value in attempting to detect circular references here is
- that only direct circular references could be detected. If the cycle involved two or more
- cells this method could not detect it.
-
- Logic to detect evaluation cycles of all kinds has been coded in EvaluationCycleDetector
- (and FormulaEvaluator).
- */
- }
-
- if (ae.isColumn()) {
- if(ae.isRow()) {
- return ae.getRelativeValue(0, 0);
- }
- if(!ae.containsRow(srcCellRow)) {
- throw EvaluationException.invalidValue();
- }
- return ae.getAbsoluteValue(srcCellRow, ae.getFirstColumn());
- }
- if(!ae.isRow()) {
- // multi-column, multi-row area
- if(ae.containsRow(srcCellRow) && ae.containsColumn(srcCellCol)) {
- return ae.getAbsoluteValue(ae.getFirstRow(), ae.getFirstColumn());
- }
- throw EvaluationException.invalidValue();
- }
- if(!ae.containsColumn(srcCellCol)) {
- throw EvaluationException.invalidValue();
- }
- return ae.getAbsoluteValue(ae.getFirstRow(), srcCellCol);
- }
-
- /**
- * Applies some conversion rules if the supplied value is not already an integer.
- * 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:
- * return (int)Math.floor(d);
- * not:
- * return (int)d; // wrong - rounds toward zero
- *
- */
- 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
- return (int)Math.floor(d);
- }
-
- /**
- * Applies some conversion rules if the supplied value is not already a number.
- * 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 {@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();
- }
- if (ev instanceof StringEval) {
- Double dd = parseDouble(((StringEval) ev).getStringValue());
- if (dd == null) {
- throw EvaluationException.invalidValue();
- }
- return dd.doubleValue();
- }
- throw new RuntimeException("Unexpected arg eval type (" + ev.getClass().getName() + ")");
- }
-
- /**
- * Converts a string to a double using standard rules that Excel would use.
- * Tolerates leading and trailing spaces,
- *
- * Doesn't support currency prefixes, commas, percentage signs or arithmetic operations strings.
- *
- * Some examples:
- * " 123 " -> 123.0
- * ".123" -> 0.123
- * "1E4" -> 1000
- * "-123" -> -123.0
- * These not supported yet:
- * " $ 1,000.00 " -> 1000.0
- * "$1.25E4" -> 12500.0
- * "5**2" -> 500
- * "250%" -> 2.5
- *
- * @return null
if the specified text cannot be parsed as a number
- */
- public static Double parseDouble(String pText) {
-
- if (Pattern.matches(fpRegex, pText))
- try {
- return Double.parseDouble(pText);
- } catch (NumberFormatException e) {
- return null;
- }
- else {
- return null;
- }
-
- }
-
- /**
- * @param ve must be a NumberEval, StringEval, BoolEval, or BlankEval
- * @return the converted string value. never null
- */
- public static String coerceValueToString(ValueEval ve) {
- if (ve instanceof StringValueEval) {
- StringValueEval sve = (StringValueEval) ve;
- return sve.getStringValue();
- }
- if (ve == BlankEval.instance) {
- return "";
- }
- throw new IllegalArgumentException("Unexpected eval class (" + ve.getClass().getName() + ")");
- }
-
- /**
- * @return null
to represent blank values
- * @throws EvaluationException if ve is an ErrorEval, or if a string value cannot be converted
- */
- public static Boolean coerceValueToBoolean(ValueEval ve, boolean stringsAreBlanks) throws EvaluationException {
-
- if (ve == null || ve == BlankEval.instance) {
- // TODO - remove 've == null' condition once AreaEval is fixed
- return null;
- }
- if (ve instanceof BoolEval) {
- return Boolean.valueOf(((BoolEval) ve).getBooleanValue());
- }
-
- if (ve == BlankEval.instance) {
- return null;
- }
-
- if (ve instanceof StringEval) {
- if (stringsAreBlanks) {
- return null;
- }
- String str = ((StringEval) ve).getStringValue();
- if (str.equalsIgnoreCase("true")) {
- return Boolean.TRUE;
- }
- if (str.equalsIgnoreCase("false")) {
- return Boolean.FALSE;
- }
- // else - string cannot be converted to boolean
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
-
- if (ve instanceof NumericValueEval) {
- NumericValueEval ne = (NumericValueEval) ve;
- double d = ne.getNumberValue();
- if (Double.isNaN(d)) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- return Boolean.valueOf(d != 0);
- }
- if (ve instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) ve);
- }
- throw new RuntimeException("Unexpected eval (" + ve.getClass().getName() + ")");
- }
-}
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
deleted file mode 100644
index 93db027b30..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java
+++ /dev/null
@@ -1,49 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-
-
-/**
- * Implementation of Excel formula token '%'.
- * @author Josh Micich
- */
-public final class PercentEval extends Fixed1ArgFunction {
-
- public static final Function instance = new PercentEval();
-
- private PercentEval() {
- // enforce singleton
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- double d;
- try {
- ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- d = OperandResolver.coerceValueToDouble(ve);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- if (d == 0.0) { // this '==' matches +0.0 and -0.0
- return NumberEval.ZERO;
- }
- return new NumberEval(d / 100);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/RangeEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/RangeEval.java
deleted file mode 100644
index 6a8186c7b7..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/RangeEval.java
+++ /dev/null
@@ -1,75 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-
-
-/**
- *
- * @author Josh Micich
- */
-public final class RangeEval extends Fixed2ArgFunction {
-
- public static final Function instance = new RangeEval();
-
- private RangeEval() {
- // enforces singleton
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
-
- try {
- AreaEval reA = evaluateRef(arg0);
- AreaEval reB = evaluateRef(arg1);
- return resolveRange(reA, reB);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- }
-
- /**
- * @return simple rectangular {@link AreaEval} which fully encloses both areas
- * aeA and aeB
- */
- private static AreaEval resolveRange(AreaEval aeA, AreaEval aeB) {
- int aeAfr = aeA.getFirstRow();
- int aeAfc = aeA.getFirstColumn();
-
- int top = Math.min(aeAfr, aeB.getFirstRow());
- int bottom = Math.max(aeA.getLastRow(), aeB.getLastRow());
- int left = Math.min(aeAfc, aeB.getFirstColumn());
- int right = Math.max(aeA.getLastColumn(), aeB.getLastColumn());
-
- return aeA.offset(top-aeAfr, bottom-aeAfr, left-aeAfc, right-aeAfc);
- }
-
- private static AreaEval evaluateRef(ValueEval arg) throws EvaluationException {
- if (arg instanceof AreaEval) {
- return (AreaEval) arg;
- }
- if (arg instanceof RefEval) {
- return ((RefEval) arg).offset(0, 0, 0, 0);
- }
- if (arg instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval)arg);
- }
- throw new IllegalArgumentException("Unexpected ref arg class (" + arg.getClass().getName() + ")");
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/RefEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/RefEval.java
deleted file mode 100644
index cb4a9e47dc..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/RefEval.java
+++ /dev/null
@@ -1,51 +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.eval;
-
-/**
- * @author Amol S Deshmukh < amolweb at ya hoo dot com >
- *
- * RefEval is the super interface for Ref2D and Ref3DEval. Basically a RefEval
- * impl should contain reference to the original ReferencePtg or Ref3DPtg as
- * well as the final "value" resulting from the evaluation of the cell
- * reference. Thus if the Cell has type CELL_TYPE_NUMERIC, the contained
- * value object should be of type NumberEval; if cell type is CELL_TYPE_STRING,
- * contained value object should be of type StringEval
- */
-public interface RefEval extends ValueEval {
-
- /**
- * @return the evaluated value of the cell referred to by this RefEval.
- */
- ValueEval getInnerValueEval();
-
- /**
- * returns the zero based column index.
- */
- int getColumn();
-
- /**
- * returns the zero based row index.
- */
- int getRow();
-
- /**
- * Creates an {@link AreaEval} offset by a relative amount from this RefEval
- */
- AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java b/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java
deleted file mode 100644
index 32cdc72e17..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/RefEvalBase.java
+++ /dev/null
@@ -1,40 +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.eval;
-
-/**
- * Common base class for implementors of {@link RefEval}
- *
- * @author Josh Micich
- */
-public abstract class RefEvalBase implements RefEval {
-
- private final int _rowIndex;
- private final int _columnIndex;
-
- protected RefEvalBase(int rowIndex, int columnIndex) {
- _rowIndex = rowIndex;
- _columnIndex = columnIndex;
- }
- public final int getRow() {
- return _rowIndex;
- }
- public final int getColumn() {
- return _columnIndex;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java
deleted file mode 100644
index b9cace26a9..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java
+++ /dev/null
@@ -1,168 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-import org.apache.poi.ss.util.NumberComparer;
-
-/**
- * Base class for all comparison operator evaluators
- *
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public abstract class RelationalOperationEval extends Fixed2ArgFunction {
-
- /**
- * Converts a standard compare result (-1, 0, 1) to true
or false
- * according to subclass' comparison type.
- */
- protected abstract boolean convertComparisonResult(int cmpResult);
-
- /**
- * This is a description of how the relational operators apply in MS Excel.
- * Use this as a guideline when testing/implementing the evaluate methods
- * for the relational operators Evals.
- *
- *
- * Bool.TRUE > any number.
- * Bool > any string. ALWAYS
- * Bool.TRUE > Bool.FALSE
- * Bool.FALSE == Blank
- *
- * Strings are never converted to numbers or booleans
- * String > any number. ALWAYS
- * Non-empty String > Blank
- * Empty String == Blank
- * String are sorted dictionary wise
- *
- * Blank > Negative numbers
- * Blank == 0
- * Blank < Positive numbers
- *
- */
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
-
- ValueEval vA;
- ValueEval vB;
- try {
- vA = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- vB = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- int cmpResult = doCompare(vA, vB);
- boolean result = convertComparisonResult(cmpResult);
- return BoolEval.valueOf(result);
- }
-
- private static int doCompare(ValueEval va, ValueEval vb) {
- // special cases when one operand is blank
- if (va == BlankEval.instance) {
- return compareBlank(vb);
- }
- if (vb == BlankEval.instance) {
- return -compareBlank(va);
- }
-
- if (va instanceof BoolEval) {
- if (vb instanceof BoolEval) {
- BoolEval bA = (BoolEval) va;
- BoolEval bB = (BoolEval) vb;
- if (bA.getBooleanValue() == bB.getBooleanValue()) {
- return 0;
- }
- return bA.getBooleanValue() ? 1 : -1;
- }
- return 1;
- }
- if (vb instanceof BoolEval) {
- return -1;
- }
- if (va instanceof StringEval) {
- if (vb instanceof StringEval) {
- StringEval sA = (StringEval) va;
- StringEval sB = (StringEval) vb;
- return sA.getStringValue().compareToIgnoreCase(sB.getStringValue());
- }
- return 1;
- }
- if (vb instanceof StringEval) {
- return -1;
- }
- if (va instanceof NumberEval) {
- if (vb instanceof NumberEval) {
- NumberEval nA = (NumberEval) va;
- NumberEval nB = (NumberEval) vb;
- return NumberComparer.compare(nA.getNumberValue(), nB.getNumberValue());
- }
- }
- throw new IllegalArgumentException("Bad operand types (" + va.getClass().getName() + "), ("
- + vb.getClass().getName() + ")");
- }
-
- private static int compareBlank(ValueEval v) {
- if (v == BlankEval.instance) {
- return 0;
- }
- if (v instanceof BoolEval) {
- BoolEval boolEval = (BoolEval) v;
- return boolEval.getBooleanValue() ? -1 : 0;
- }
- if (v instanceof NumberEval) {
- NumberEval ne = (NumberEval) v;
- return NumberComparer.compare(0.0, ne.getNumberValue());
- }
- if (v instanceof StringEval) {
- StringEval se = (StringEval) v;
- return se.getStringValue().length() < 1 ? 0 : -1;
- }
- throw new IllegalArgumentException("bad value class (" + v.getClass().getName() + ")");
- }
-
- public static final Function EqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult == 0;
- }
- };
- public static final Function GreaterEqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult >= 0;
- }
- };
- public static final Function GreaterThanEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult > 0;
- }
- };
- public static final Function LessEqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult <= 0;
- }
- };
- public static final Function LessThanEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult < 0;
- }
- };
- public static final Function NotEqualEval = new RelationalOperationEval() {
- protected boolean convertComparisonResult(int cmpResult) {
- return cmpResult != 0;
- }
- };
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/StringEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/StringEval.java
deleted file mode 100644
index 9c686dbe29..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/StringEval.java
+++ /dev/null
@@ -1,54 +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.eval;
-
-import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.StringPtg;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public final class StringEval implements StringValueEval {
-
- public static final StringEval EMPTY_INSTANCE = new StringEval("");
-
- private final String _value;
-
- public StringEval(Ptg ptg) {
- this(((StringPtg) ptg).getValue());
- }
-
- public StringEval(String value) {
- if (value == null) {
- throw new IllegalArgumentException("value must not be null");
- }
- _value = value;
- }
-
- public String getStringValue() {
- return _value;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(_value);
- sb.append("]");
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/StringValueEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/StringValueEval.java
deleted file mode 100644
index 46c12236b9..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/StringValueEval.java
+++ /dev/null
@@ -1,30 +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.eval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public interface StringValueEval extends ValueEval {
-
- /**
- * @return never null
, possibly empty string.
- */
- String getStringValue();
-}
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
deleted file mode 100644
index 7e6ac88364..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/TwoOperandNumericOperation.java
+++ /dev/null
@@ -1,87 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-
-/**
- * @author Josh Micich
- */
-public abstract class TwoOperandNumericOperation extends Fixed2ArgFunction {
-
- protected final double singleOperandEvaluate(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
- return OperandResolver.coerceValueToDouble(ve);
- }
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
- double result;
- try {
- double d0 = singleOperandEvaluate(arg0, srcRowIndex, srcColumnIndex);
- double d1 = singleOperandEvaluate(arg1, srcRowIndex, srcColumnIndex);
- result = evaluate(d0, d1);
- if (result == 0.0) { // this '==' matches +0.0 and -0.0
- // Excel converts -0.0 to +0.0 for '*', '/', '%', '+' and '^'
- if (!(this instanceof SubtractEvalClass)) {
- return NumberEval.ZERO;
- }
- }
- if (Double.isNaN(result) || Double.isInfinite(result)) {
- return ErrorEval.NUM_ERROR;
- }
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new NumberEval(result);
- }
-
- protected abstract double evaluate(double d0, double d1) throws EvaluationException;
-
- public static final Function AddEval = new TwoOperandNumericOperation() {
- protected double evaluate(double d0, double d1) {
- return d0+d1;
- }
- };
- public static final Function DivideEval = new TwoOperandNumericOperation() {
- protected double evaluate(double d0, double d1) throws EvaluationException {
- if (d1 == 0.0) {
- throw new EvaluationException(ErrorEval.DIV_ZERO);
- }
- return d0/d1;
- }
- };
- public static final Function MultiplyEval = new TwoOperandNumericOperation() {
- protected double evaluate(double d0, double d1) {
- return d0*d1;
- }
- };
- public static final Function PowerEval = new TwoOperandNumericOperation() {
- protected double evaluate(double d0, double d1) {
- return Math.pow(d0, d1);
- }
- };
- private static final class SubtractEvalClass extends TwoOperandNumericOperation {
- public SubtractEvalClass() {
- //
- }
- protected double evaluate(double d0, double d1) {
- return d0-d1;
- }
- }
- public static final Function SubtractEval = new SubtractEvalClass();
-}
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
deleted file mode 100644
index ba5f197dce..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java
+++ /dev/null
@@ -1,47 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public final class UnaryMinusEval extends Fixed1ArgFunction {
-
- public static final Function instance = new UnaryMinusEval();
-
- private UnaryMinusEval() {
- // enforce singleton
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- double d;
- try {
- ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- d = OperandResolver.coerceValueToDouble(ve);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- if (d == 0.0) { // this '==' matches +0.0 and -0.0
- return NumberEval.ZERO;
- }
- return new NumberEval(-d);
- }
-}
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
deleted file mode 100644
index b6f32e9b61..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java
+++ /dev/null
@@ -1,51 +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.eval;
-
-import org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction;
-import org.apache.poi.hssf.record.formula.functions.Function;
-
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public final class UnaryPlusEval extends Fixed1ArgFunction {
-
- public static final Function instance = new UnaryPlusEval();
-
- private UnaryPlusEval() {
- // enforce singleton
- }
-
- public ValueEval evaluate(int srcCellRow, int srcCellCol, ValueEval arg0) {
- double d;
- try {
- ValueEval ve = OperandResolver.getSingleValue(arg0, srcCellRow, srcCellCol);
- if(ve instanceof StringEval) {
- // Note - asymmetric with UnaryMinus
- // -"hello" evaluates to #VALUE!
- // but +"hello" evaluates to "hello"
- return ve;
- }
- d = OperandResolver.coerceValueToDouble(ve);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new NumberEval(+d);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/ValueEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/ValueEval.java
deleted file mode 100644
index 9b6bbae6d8..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/eval/ValueEval.java
+++ /dev/null
@@ -1,25 +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.eval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public interface ValueEval {
- // no methods
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/function/FunctionDataBuilder.java b/src/java/org/apache/poi/hssf/record/formula/function/FunctionDataBuilder.java
deleted file mode 100644
index 5f173a12db..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/function/FunctionDataBuilder.java
+++ /dev/null
@@ -1,91 +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.function;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Temporarily collects FunctionMetadata instances for creation of a
- * FunctionMetadataRegistry.
- *
- * @author Josh Micich
- */
-final class FunctionDataBuilder {
- private int _maxFunctionIndex;
- private final Map _functionDataByName;
- private final Map _functionDataByIndex;
- /** stores indexes of all functions with footnotes (i.e. whose definitions might change) */
- private final Set _mutatingFunctionIndexes;
-
- public FunctionDataBuilder(int sizeEstimate) {
- _maxFunctionIndex = -1;
- _functionDataByName = new HashMap(sizeEstimate * 3 / 2);
- _functionDataByIndex = new HashMap(sizeEstimate * 3 / 2);
- _mutatingFunctionIndexes = new HashSet();
- }
-
- public void add(int functionIndex, String functionName, int minParams, int maxParams,
- byte returnClassCode, byte[] parameterClassCodes, boolean hasFootnote) {
- FunctionMetadata fm = new FunctionMetadata(functionIndex, functionName, minParams, maxParams,
- returnClassCode, parameterClassCodes);
-
- Integer indexKey = Integer.valueOf(functionIndex);
-
-
- if(functionIndex > _maxFunctionIndex) {
- _maxFunctionIndex = functionIndex;
- }
- // allow function definitions to change only if both previous and the new items have footnotes
- FunctionMetadata prevFM;
- prevFM = (FunctionMetadata) _functionDataByName.get(functionName);
- if(prevFM != null) {
- if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
- throw new RuntimeException("Multiple entries for function name '" + functionName + "'");
- }
- _functionDataByIndex.remove(Integer.valueOf(prevFM.getIndex()));
- }
- prevFM = (FunctionMetadata) _functionDataByIndex.get(indexKey);
- if(prevFM != null) {
- if(!hasFootnote || !_mutatingFunctionIndexes.contains(indexKey)) {
- throw new RuntimeException("Multiple entries for function index (" + functionIndex + ")");
- }
- _functionDataByName.remove(prevFM.getName());
- }
- if(hasFootnote) {
- _mutatingFunctionIndexes.add(indexKey);
- }
- _functionDataByIndex.put(indexKey, fm);
- _functionDataByName.put(functionName, fm);
- }
-
- public FunctionMetadataRegistry build() {
-
- FunctionMetadata[] jumbledArray = new FunctionMetadata[_functionDataByName.size()];
- _functionDataByName.values().toArray(jumbledArray);
- FunctionMetadata[] fdIndexArray = new FunctionMetadata[_maxFunctionIndex+1];
- for (int i = 0; i < jumbledArray.length; i++) {
- FunctionMetadata fd = jumbledArray[i];
- fdIndexArray[fd.getIndex()] = fd;
- }
-
- return new FunctionMetadataRegistry(fdIndexArray, _functionDataByName);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadata.java b/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadata.java
deleted file mode 100644
index 898a72ad44..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadata.java
+++ /dev/null
@@ -1,92 +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.function;
-
-import org.apache.poi.ss.SpreadsheetVersion;
-
-/**
- * Holds information about Excel built-in functions.
- *
- * @author Josh Micich
- */
-public final class FunctionMetadata {
- /**
- * maxParams=30 in functionMetadata.txt means the maximum number arguments supported
- * by the given version of Excel. Validation routines should take the actual limit (Excel 97 or 2007)
- * from the SpreadsheetVersion enum.
- * Perhaps a value like 'M' should be used instead of '30' in functionMetadata.txt
- * to make that file more version neutral.
- * @see org.apache.poi.ss.formula.FormulaParser#validateNumArgs(int, FunctionMetadata)
- */
- private static final short FUNCTION_MAX_PARAMS = 30;
-
- private final int _index;
- private final String _name;
- private final int _minParams;
- private final int _maxParams;
- private final byte _returnClassCode;
- private final byte[] _parameterClassCodes;
-
- /* package */ FunctionMetadata(int index, String name, int minParams, int maxParams,
- byte returnClassCode, byte[] parameterClassCodes) {
- _index = index;
- _name = name;
- _minParams = minParams;
- _maxParams = maxParams;
- _returnClassCode = returnClassCode;
- _parameterClassCodes = parameterClassCodes;
- }
- public int getIndex() {
- return _index;
- }
- public String getName() {
- return _name;
- }
- public int getMinParams() {
- return _minParams;
- }
- public int getMaxParams() {
- return _maxParams;
- }
- public boolean hasFixedArgsLength() {
- return _minParams == _maxParams;
- }
- public byte getReturnClassCode() {
- return _returnClassCode;
- }
- public byte[] getParameterClassCodes() {
- return _parameterClassCodes.clone();
- }
- /**
- * Some varags functions (like VLOOKUP) have a specific limit to the number of arguments that
- * can be passed. Other functions (like SUM) don't have such a limit. For those functions,
- * the spreadsheet version determines the maximum number of arguments that can be passed.
- * @return true
if this function can the maximum number of arguments allowable by
- * the {@link SpreadsheetVersion}
- */
- public boolean hasUnlimitedVarags() {
- return FUNCTION_MAX_PARAMS == _maxParams;
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(_index).append(" ").append(_name);
- sb.append("]");
- return sb.toString();
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java b/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java
deleted file mode 100644
index 5ce7327199..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataReader.java
+++ /dev/null
@@ -1,195 +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.function;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import org.apache.poi.hssf.record.formula.Ptg;
-
-/**
- * Converts the text meta-data file into a FunctionMetadataRegistry
- *
- * @author Josh Micich
- */
-final class FunctionMetadataReader {
-
- private static final String METADATA_FILE_NAME = "functionMetadata.txt";
-
- /** plain ASCII text metadata file uses three dots for ellipsis */
- private static final String ELLIPSIS = "...";
-
- private static final Pattern TAB_DELIM_PATTERN = Pattern.compile("\t");
- private static final Pattern SPACE_DELIM_PATTERN = Pattern.compile(" ");
- private static final byte[] EMPTY_BYTE_ARRAY = { };
-
- private static final String[] DIGIT_ENDING_FUNCTION_NAMES = {
- // Digits at the end of a function might be due to a left-over footnote marker.
- // except in these cases
- "LOG10", "ATAN2", "DAYS360", "SUMXMY2", "SUMX2MY2", "SUMX2PY2",
- };
- private static final Set DIGIT_ENDING_FUNCTION_NAMES_SET = new HashSet(Arrays.asList(DIGIT_ENDING_FUNCTION_NAMES));
-
- public static FunctionMetadataRegistry createRegistry() {
- InputStream is = FunctionMetadataReader.class.getResourceAsStream(METADATA_FILE_NAME);
- if (is == null) {
- throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found");
- }
-
- BufferedReader br;
- try {
- br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
- } catch(UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- FunctionDataBuilder fdb = new FunctionDataBuilder(400);
-
- try {
- while (true) {
- String line = br.readLine();
- if (line == null) {
- break;
- }
- if (line.length() < 1 || line.charAt(0) == '#') {
- continue;
- }
- String trimLine = line.trim();
- if (trimLine.length() < 1) {
- continue;
- }
- processLine(fdb, line);
- }
- br.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
-
- return fdb.build();
- }
-
- private static void processLine(FunctionDataBuilder fdb, String line) {
-
- String[] parts = TAB_DELIM_PATTERN.split(line, -2);
- if(parts.length != 8) {
- throw new RuntimeException("Bad line format '" + line + "' - expected 8 data fields");
- }
- int functionIndex = parseInt(parts[0]);
- String functionName = parts[1];
- int minParams = parseInt(parts[2]);
- int maxParams = parseInt(parts[3]);
- byte returnClassCode = parseReturnTypeCode(parts[4]);
- byte[] parameterClassCodes = parseOperandTypeCodes(parts[5]);
- // 6 isVolatile
- boolean hasNote = parts[7].length() > 0;
-
- validateFunctionName(functionName);
- // TODO - make POI use isVolatile
- fdb.add(functionIndex, functionName, minParams, maxParams,
- returnClassCode, parameterClassCodes, hasNote);
- }
-
-
- private static byte parseReturnTypeCode(String code) {
- if(code.length() == 0) {
- return Ptg.CLASS_REF; // happens for GETPIVOTDATA
- }
- return parseOperandTypeCode(code);
- }
-
- private static byte[] parseOperandTypeCodes(String codes) {
- if(codes.length() < 1) {
- return EMPTY_BYTE_ARRAY; // happens for GETPIVOTDATA
- }
- if(isDash(codes)) {
- // '-' means empty:
- return EMPTY_BYTE_ARRAY;
- }
- String[] array = SPACE_DELIM_PATTERN.split(codes);
- int nItems = array.length;
- if(ELLIPSIS.equals(array[nItems-1])) {
- // final ellipsis is optional, and ignored
- // (all unspecified params are assumed to be the same as the last)
- nItems --;
- }
- byte[] result = new byte[nItems];
- for (int i = 0; i < nItems; i++) {
- result[i] = parseOperandTypeCode(array[i]);
- }
- return result;
- }
-
- private static boolean isDash(String codes) {
- if(codes.length() == 1) {
- switch (codes.charAt(0)) {
- case '-':
- return true;
- }
- }
- return false;
- }
-
- private static byte parseOperandTypeCode(String code) {
- if(code.length() != 1) {
- throw new RuntimeException("Bad operand type code format '" + code + "' expected single char");
- }
- switch(code.charAt(0)) {
- case 'V': return Ptg.CLASS_VALUE;
- case 'R': return Ptg.CLASS_REF;
- case 'A': return Ptg.CLASS_ARRAY;
- }
- throw new IllegalArgumentException("Unexpected operand type code '" + code + "' (" + (int)code.charAt(0) + ")");
- }
-
- /**
- * Makes sure that footnote digits from the original OOO document have not been accidentally
- * left behind
- */
- private static void validateFunctionName(String functionName) {
- int len = functionName.length();
- int ix = len - 1;
- if (!Character.isDigit(functionName.charAt(ix))) {
- return;
- }
- while(ix >= 0) {
- if (!Character.isDigit(functionName.charAt(ix))) {
- break;
- }
- ix--;
- }
- if(DIGIT_ENDING_FUNCTION_NAMES_SET.contains(functionName)) {
- return;
- }
- throw new RuntimeException("Invalid function name '" + functionName
- + "' (is footnote number incorrectly appended)");
- }
-
- private static int parseInt(String valStr) {
- try {
- return Integer.parseInt(valStr);
- } catch (NumberFormatException e) {
- throw new RuntimeException("Value '" + valStr + "' could not be parsed as an integer");
- }
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java b/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java
deleted file mode 100644
index 97891c1100..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/function/FunctionMetadataRegistry.java
+++ /dev/null
@@ -1,90 +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.function;
-
-import java.util.Map;
-import java.util.Set;
-/**
- * Allows clients to get {@link FunctionMetadata} instances for any built-in function of Excel.
- *
- * @author Josh Micich
- */
-public final class FunctionMetadataRegistry {
- /**
- * The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
- */
- public static final String FUNCTION_NAME_IF = "IF";
-
- public static final int FUNCTION_INDEX_IF = 1;
- public static final short FUNCTION_INDEX_SUM = 4;
- public static final int FUNCTION_INDEX_CHOOSE = 100;
- public static final short FUNCTION_INDEX_INDIRECT = 148;
- public static final short FUNCTION_INDEX_EXTERNAL = 255;
-
- private static FunctionMetadataRegistry _instance;
-
- private final FunctionMetadata[] _functionDataByIndex;
- private final Map
- *
- *
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public abstract class BooleanFunction implements Function {
-
- public final ValueEval evaluate(ValueEval[] args, int srcRow, int srcCol) {
- if (args.length < 1) {
- return ErrorEval.VALUE_INVALID;
- }
- boolean boolResult;
- try {
- boolResult = calculate(args);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return BoolEval.valueOf(boolResult);
- }
-
- private boolean calculate(ValueEval[] args) throws EvaluationException {
-
- boolean result = getInitialResultValue();
- boolean atleastOneNonBlank = false;
-
- /*
- * Note: no short-circuit boolean loop exit because any ErrorEvals will override the result
- */
- for (int i=0, iSize=args.length; i
- *
- *
- * range is the range of cells to count blanks
- * Syntax: COUNTIF ( range, criteria ) - *
range | is the range of cells to be counted based on the criteria |
---|---|
criteria | is used to determine which cells to count |
null
if the specified value contains no special wildcard characters.
- */
- private static Pattern getWildCardPattern(String value) {
- int len = value.length();
- StringBuffer sb = new StringBuffer(len);
- boolean hasWildCard = false;
- for(int i=0; i
- * Syntax:
- * ERROR.TYPE(errorValue)
- * Returns a number corresponding to the error type of the supplied argument.
- *- *
errorValue | Return Value |
#NULL! | 1 |
#DIV/0! | 2 |
#VALUE! | 3 |
#REF! | 4 |
#NAME? | 5 |
#NUM! | 6 |
#N/A! | 7 |
everything else | #N/A! |
- * p(1+r)^n + y(1+rt)((1+r)^n-1)/r + f=0 ...{when r!=0} - * ny + p + f=0 ...{when r=0} - *- */ -final class FinanceLib { - - private FinanceLib() { - // no instances of this class - } - - /** - * Future value of an amount given the number of payments, rate, amount - * of individual payment, present value and boolean value indicating whether - * payments are due at the beginning of period - * (false => payments are due at end of period) - * @param r rate - * @param n num of periods - * @param y pmt per period - * @param p future value - * @param t type (true=pmt at end of period, false=pmt at begining of period) - */ - public static double fv(double r, double n, double y, double p, boolean t) { - double retval = 0; - if (r == 0) { - retval = -1*(p+(n*y)); - } - else { - double r1 = r + 1; - retval =((1-Math.pow(r1, n)) * (t ? r1 : 1) * y ) / r - - - p*Math.pow(r1, n); - } - return retval; - } - - /** - * Present value of an amount given the number of future payments, rate, amount - * of individual payment, future value and boolean value indicating whether - * payments are due at the beginning of period - * (false => payments are due at end of period) - * @param r - * @param n - * @param y - * @param f - * @param t - */ - public static double pv(double r, double n, double y, double f, boolean t) { - double retval = 0; - if (r == 0) { - retval = -1*((n*y)+f); - } - else { - double r1 = r + 1; - retval =(( ( 1 - Math.pow(r1, n) ) / r ) * (t ? r1 : 1) * y - f) - / - Math.pow(r1, n); - } - return retval; - } - - /** - * calculates the Net Present Value of a principal amount - * given the discount rate and a sequence of cash flows - * (supplied as an array). If the amounts are income the value should - * be positive, else if they are payments and not income, the - * value should be negative. - * @param r - * @param cfs cashflow amounts - */ - public static double npv(double r, double[] cfs) { - double npv = 0; - double r1 = r + 1; - double trate = r1; - for (int i=0, iSize=cfs.length; i
null
,
- * nor are any of its elements.
- * @param ec primarily used to identify the source cell containing the formula being evaluated.
- * may also be used to dynamically create reference evals.
- * @return never null
. Possibly an instance of ErrorEval in the case of
- * a specified Excel error (Exceptions are never thrown to represent Excel errors).
- */
- ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function.java
deleted file mode 100644
index 92505ecd03..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Function.java
+++ /dev/null
@@ -1,43 +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.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * Common interface for all implementations of Excel built-in functions.
- *
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- */
-public interface Function {
-
- /**
- * @param args the evaluated function arguments. Empty values are represented with
- * {@link BlankEval} or {@link MissingArgEval}, never null
.
- * @param srcRowIndex row index of the cell containing the formula under evaluation
- * @param srcColumnIndex column index of the cell containing the formula under evaluation
- * @return The evaluated result, possibly an {@link ErrorEval}, never null
.
- * Note - Excel uses the error code #NUM! instead of IEEE NaN, so when
- * numeric functions evaluate to {@link Double#NaN} be sure to translate the result to {@link
- * ErrorEval#NUM_ERROR}.
- */
- ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function0Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function0Arg.java
deleted file mode 100644
index c61a87e0a2..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Function0Arg.java
+++ /dev/null
@@ -1,32 +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.record.formula.eval.ValueEval;
-
-/**
- * Implemented by all functions that can be called with zero arguments
- *
- * @author Josh Micich
- */
-public interface Function0Arg extends Function {
- /**
- * see {@link Function#evaluate(ValueEval[], int, int)}
- */
- ValueEval evaluate(int srcRowIndex, int srcColumnIndex);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function1Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function1Arg.java
deleted file mode 100644
index 42007fa4cc..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Function1Arg.java
+++ /dev/null
@@ -1,32 +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.record.formula.eval.ValueEval;
-
-/**
- * Implemented by all functions that can be called with one argument
- *
- * @author Josh Micich
- */
-public interface Function1Arg extends Function {
- /**
- * see {@link Function#evaluate(ValueEval[], int, int)}
- */
- ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function2Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function2Arg.java
deleted file mode 100644
index b0ef472859..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Function2Arg.java
+++ /dev/null
@@ -1,32 +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.record.formula.eval.ValueEval;
-
-/**
- * Implemented by all functions that can be called with two arguments
- *
- * @author Josh Micich
- */
-public interface Function2Arg extends Function {
- /**
- * see {@link Function#evaluate(ValueEval[], int, int)}
- */
- ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function3Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function3Arg.java
deleted file mode 100644
index 7ee32b81c2..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Function3Arg.java
+++ /dev/null
@@ -1,32 +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.record.formula.eval.ValueEval;
-
-/**
- * Implemented by all functions that can be called with three arguments
- *
- * @author Josh Micich
- */
-public interface Function3Arg extends Function {
- /**
- * see {@link Function#evaluate(ValueEval[], int, int)}
- */
- ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Function4Arg.java b/src/java/org/apache/poi/hssf/record/formula/functions/Function4Arg.java
deleted file mode 100644
index 7089432f75..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Function4Arg.java
+++ /dev/null
@@ -1,32 +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.record.formula.eval.ValueEval;
-
-/**
- * Implemented by all functions that can be called with four arguments
- *
- * @author Josh Micich
- */
-public interface Function4Arg extends Function {
- /**
- * see {@link Function#evaluate(ValueEval[], int, int)}
- */
- ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2, ValueEval arg3);
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java b/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java
deleted file mode 100644
index df5ecad6ef..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java
+++ /dev/null
@@ -1,80 +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.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.EvaluationException;
-import org.apache.poi.hssf.record.formula.eval.OperandResolver;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
-import org.apache.poi.ss.formula.TwoDEval;
-/**
- * Implementation of the HLOOKUP() function.
- *
- * HLOOKUP finds a column in a lookup table by the first row value and returns the value from another row.
- *
- * Syntax :
- * INDEX ( reference, row_num[, column_num [, area_num]])
- * INDEX ( array, row_num[, column_num])
- *
reference | typically an area reference, possibly a union of areas |
---|---|
array | a literal array value (currently not supported) |
row_num | selects the row within the array or area reference |
column_num | selects column within the array or area reference. default is 1 |
area_num | used when reference is a union of areas |
null
if text cannot be parsed.
- */
- private static String[] parseWorkbookAndSheetName(CharSequence text) {
- int lastIx = text.length() - 1;
- if (lastIx < 0) {
- return null;
- }
- if (canTrim(text)) {
- return null;
- }
- char firstChar = text.charAt(0);
- if (Character.isWhitespace(firstChar)) {
- return null;
- }
- if (firstChar == '\'') {
- // workbookName or sheetName needs quoting
- // quotes go around both
- if (text.charAt(lastIx) != '\'') {
- return null;
- }
- firstChar = text.charAt(1);
- if (Character.isWhitespace(firstChar)) {
- return null;
- }
- String wbName;
- int sheetStartPos;
- if (firstChar == '[') {
- int rbPos = text.toString().lastIndexOf(']');
- if (rbPos < 0) {
- return null;
- }
- wbName = unescapeString(text.subSequence(2, rbPos));
- if (wbName == null || canTrim(wbName)) {
- return null;
- }
- sheetStartPos = rbPos + 1;
- } else {
- wbName = null;
- sheetStartPos = 1;
- }
-
- // else - just sheet name
- String sheetName = unescapeString(text.subSequence(sheetStartPos, lastIx));
- if (sheetName == null) { // note - when quoted, sheetName can
- // start/end with whitespace
- return null;
- }
- return new String[] { wbName, sheetName, };
- }
-
- if (firstChar == '[') {
- int rbPos = text.toString().lastIndexOf(']');
- if (rbPos < 0) {
- return null;
- }
- CharSequence wbName = text.subSequence(1, rbPos);
- if (canTrim(wbName)) {
- return null;
- }
- CharSequence sheetName = text.subSequence(rbPos + 1, text.length());
- if (canTrim(sheetName)) {
- return null;
- }
- return new String[] { wbName.toString(), sheetName.toString(), };
- }
- // else - just sheet name
- return new String[] { null, text.toString(), };
- }
-
- /**
- * @return null
if there is a syntax error in any escape sequence
- * (the typical syntax error is a single quote character not followed by another).
- */
- private static String unescapeString(CharSequence text) {
- int len = text.length();
- StringBuilder sb = new StringBuilder(len);
- int i = 0;
- while (i < len) {
- char ch = text.charAt(i);
- if (ch == '\'') {
- // every quote must be followed by another
- i++;
- if (i >= len) {
- return null;
- }
- ch = text.charAt(i);
- if (ch != '\'') {
- return null;
- }
- }
- sb.append(ch);
- i++;
- }
- return sb.toString();
- }
-
- private static boolean canTrim(CharSequence text) {
- int lastIx = text.length() - 1;
- if (lastIx < 0) {
- return false;
- }
- if (Character.isWhitespace(text.charAt(0))) {
- return true;
- }
- if (Character.isWhitespace(text.charAt(lastIx))) {
- return true;
- }
- return false;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java
deleted file mode 100644
index 206dd41b68..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java
+++ /dev/null
@@ -1,119 +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.record.formula.eval.AreaEval;
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-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.RefEval;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- * @author Josh Micich
- */
-public abstract class LogicalFunction extends Fixed1ArgFunction {
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- ValueEval ve;
- try {
- ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- if (false) {
- // Note - it is more usual to propagate error codes straight to the result like this:
- return e.getErrorEval();
- // but logical functions behave a little differently
- }
- // this will usually cause a 'FALSE' result except for ISNONTEXT()
- ve = e.getErrorEval();
- }
- return BoolEval.valueOf(evaluate(ve));
-
- }
- /**
- * @param arg any {@link ValueEval}, potentially {@link BlankEval} or {@link ErrorEval}.
- */
- protected abstract boolean evaluate(ValueEval arg);
-
- public static final Function ISLOGICAL = new LogicalFunction() {
- protected boolean evaluate(ValueEval arg) {
- return arg instanceof BoolEval;
- }
- };
- public static final Function ISNONTEXT = new LogicalFunction() {
- protected boolean evaluate(ValueEval arg) {
- return !(arg instanceof StringEval);
- }
- };
- public static final Function ISNUMBER = new LogicalFunction() {
- protected boolean evaluate(ValueEval arg) {
- return arg instanceof NumberEval;
- }
- };
- public static final Function ISTEXT = new LogicalFunction() {
- protected boolean evaluate(ValueEval arg) {
- return arg instanceof StringEval;
- }
- };
-
- public static final Function ISBLANK = new LogicalFunction() {
-
- protected boolean evaluate(ValueEval arg) {
- return arg instanceof BlankEval;
- }
- };
-
- public static final Function ISERROR = new LogicalFunction() {
-
- protected boolean evaluate(ValueEval arg) {
- return arg instanceof ErrorEval;
- }
- };
-
- /**
- * Implementation for Excel ISNA() function.
- *
- * Syntax:null
if the supplied area is neither a single row nor a single colum
- */
- public static ValueVector createVector(TwoDEval ae) {
- if (ae.isColumn()) {
- return createColumnVector(ae, 0);
- }
- if (ae.isRow()) {
- return createRowVector(ae, 0);
- }
- return null;
- }
-
- /**
- * Enumeration to support 4 valued comparison results.
- * Excel lookup functions have complex behaviour in the case where the lookup array has mixed
- * types, and/or is unordered. Contrary to suggestions in some Excel documentation, there
- * does not appear to be a universal ordering across types. The binary search algorithm used
- * changes behaviour when the evaluated 'mid' value has a different type to the lookup value.
- *
- * A simple int might have done the same job, but there is risk in confusion with the well
- * known Comparable.compareTo() and Comparator.compare() which both use
- * a ubiquitous 3 value result encoding.
- */
- public static final class CompareResult {
- private final boolean _isTypeMismatch;
- private final boolean _isLessThan;
- private final boolean _isEqual;
- private final boolean _isGreaterThan;
-
- private CompareResult(boolean isTypeMismatch, int simpleCompareResult) {
- if(isTypeMismatch) {
- _isTypeMismatch = true;
- _isLessThan = false;
- _isEqual = false;
- _isGreaterThan = false;
- } else {
- _isTypeMismatch = false;
- _isLessThan = simpleCompareResult < 0;
- _isEqual = simpleCompareResult == 0;
- _isGreaterThan = simpleCompareResult > 0;
- }
- }
- public static final CompareResult TYPE_MISMATCH = new CompareResult(true, 0);
- public static final CompareResult LESS_THAN = new CompareResult(false, -1);
- public static final CompareResult EQUAL = new CompareResult(false, 0);
- public static final CompareResult GREATER_THAN = new CompareResult(false, +1);
-
- public static final CompareResult valueOf(int simpleCompareResult) {
- if(simpleCompareResult < 0) {
- return LESS_THAN;
- }
- if(simpleCompareResult > 0) {
- return GREATER_THAN;
- }
- return EQUAL;
- }
-
- public boolean isTypeMismatch() {
- return _isTypeMismatch;
- }
- public boolean isLessThan() {
- return _isLessThan;
- }
- public boolean isEqual() {
- return _isEqual;
- }
- public boolean isGreaterThan() {
- return _isGreaterThan;
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(formatAsString());
- sb.append("]");
- return sb.toString();
- }
-
- private String formatAsString() {
- if(_isTypeMismatch) {
- return "TYPE_MISMATCH";
- }
- if(_isLessThan) {
- return "LESS_THAN";
- }
- if(_isEqual) {
- return "EQUAL";
- }
- if(_isGreaterThan) {
- return "GREATER_THAN";
- }
- // toString must be reliable
- return "??error??";
- }
- }
-
- public interface LookupValueComparer {
- /**
- * @return one of 4 instances or CompareResult: LESS_THAN, EQUAL,
- * GREATER_THAN or TYPE_MISMATCH
- */
- CompareResult compareTo(ValueEval other);
- }
-
- private static abstract class LookupValueComparerBase implements LookupValueComparer {
-
- private final Class extends ValueEval> _targetClass;
- protected LookupValueComparerBase(ValueEval targetValue) {
- if(targetValue == null) {
- throw new RuntimeException("targetValue cannot be null");
- }
- _targetClass = targetValue.getClass();
- }
- public final CompareResult compareTo(ValueEval other) {
- if (other == null) {
- throw new RuntimeException("compare to value cannot be null");
- }
- if (_targetClass != other.getClass()) {
- return CompareResult.TYPE_MISMATCH;
- }
- return compareSameType(other);
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(getValueAsString());
- sb.append("]");
- return sb.toString();
- }
- protected abstract CompareResult compareSameType(ValueEval other);
- /** used only for debug purposes */
- protected abstract String getValueAsString();
- }
-
- private static final class StringLookupComparer extends LookupValueComparerBase {
- private String _value;
-
- protected StringLookupComparer(StringEval se) {
- super(se);
- _value = se.getStringValue();
- }
- protected CompareResult compareSameType(ValueEval other) {
- StringEval se = (StringEval) other;
- return CompareResult.valueOf(_value.compareToIgnoreCase(se.getStringValue()));
- }
- protected String getValueAsString() {
- return _value;
- }
- }
- private static final class NumberLookupComparer extends LookupValueComparerBase {
- private double _value;
-
- protected NumberLookupComparer(NumberEval ne) {
- super(ne);
- _value = ne.getNumberValue();
- }
- protected CompareResult compareSameType(ValueEval other) {
- NumberEval ne = (NumberEval) other;
- return CompareResult.valueOf(Double.compare(_value, ne.getNumberValue()));
- }
- protected String getValueAsString() {
- return String.valueOf(_value);
- }
- }
- private static final class BooleanLookupComparer extends LookupValueComparerBase {
- private boolean _value;
-
- protected BooleanLookupComparer(BoolEval be) {
- super(be);
- _value = be.getBooleanValue();
- }
- protected CompareResult compareSameType(ValueEval other) {
- BoolEval be = (BoolEval) other;
- boolean otherVal = be.getBooleanValue();
- if(_value == otherVal) {
- return CompareResult.EQUAL;
- }
- // TRUE > FALSE
- if(_value) {
- return CompareResult.GREATER_THAN;
- }
- return CompareResult.LESS_THAN;
- }
- protected String getValueAsString() {
- return String.valueOf(_value);
- }
- }
-
- /**
- * Processes the third argument to VLOOKUP, or HLOOKUP (col_index_num
- * or row_index_num respectively).Input Return | Value | Thrown Error |
---|---|---|
5 | 4 | |
2.9 | 2 | |
"5" | 4 | |
"2.18e1" | 21 | |
"-$2" | -3 | * |
FALSE | -1 | * |
TRUE | 0 | |
"TRUE" | #REF! | |
"abc" | #REF! | |
"" | #REF! | |
<blank> | #VALUE! |
null
- */
- public static boolean resolveRangeLookupArg(ValueEval rangeLookupArg, int srcCellRow, int srcCellCol) throws EvaluationException {
-
- ValueEval valEval = OperandResolver.getSingleValue(rangeLookupArg, srcCellRow, srcCellCol);
- if(valEval instanceof BlankEval) {
- // Tricky:
- // fourth arg supplied but evaluates to blank
- // this does not get the default value
- return false;
- }
- if(valEval instanceof BoolEval) {
- // Happy day flow
- BoolEval boolEval = (BoolEval) valEval;
- return boolEval.getBooleanValue();
- }
-
- if (valEval instanceof StringEval) {
- String stringValue = ((StringEval) valEval).getStringValue();
- if(stringValue.length() < 1) {
- // More trickiness:
- // Empty string is not the same as BlankEval. It causes #VALUE! error
- throw EvaluationException.invalidValue();
- }
- // TODO move parseBoolean to OperandResolver
- Boolean b = Countif.parseBoolean(stringValue);
- if(b != null) {
- // string converted to boolean OK
- return b.booleanValue();
- }
- // Even more trickiness:
- // Note - even if the StringEval represents a number value (for example "1"),
- // Excel does not resolve it to a boolean.
- throw EvaluationException.invalidValue();
- // This is in contrast to the code below,, where NumberEvals values (for
- // example 0.01) *do* resolve to equivalent boolean values.
- }
- if (valEval instanceof NumericValueEval) {
- NumericValueEval nve = (NumericValueEval) valEval;
- // zero is FALSE, everything else is TRUE
- return 0.0 != nve.getNumberValue();
- }
- throw new RuntimeException("Unexpected eval type (" + valEval.getClass().getName() + ")");
- }
-
- public static int lookupIndexOfValue(ValueEval lookupValue, ValueVector vector, boolean isRangeLookup) throws EvaluationException {
- LookupValueComparer lookupComparer = createLookupComparer(lookupValue);
- int result;
- if(isRangeLookup) {
- result = performBinarySearch(vector, lookupComparer);
- } else {
- result = lookupIndexOfExactValue(lookupComparer, vector);
- }
- if(result < 0) {
- throw new EvaluationException(ErrorEval.NA);
- }
- return result;
- }
-
-
- /**
- * Finds first (lowest index) exact occurrence of specified value.
- * @param lookupValue the value to be found in column or row vector
- * @param vector the values to be searched. For VLOOKUP this is the first column of the
- * tableArray. For HLOOKUP this is the first row of the tableArray.
- * @return zero based index into the vector, -1 if value cannot be found
- */
- private static int lookupIndexOfExactValue(LookupValueComparer lookupComparer, ValueVector vector) {
-
- // find first occurrence of lookup value
- int size = vector.getSize();
- for (int i = 0; i < size; i++) {
- if(lookupComparer.compareTo(vector.getItem(i)).isEqual()) {
- return i;
- }
- }
- return -1;
- }
-
-
- /**
- * Encapsulates some standard binary search functionality so the unusual Excel behaviour can
- * be clearly distinguished.
- */
- private static final class BinarySearchIndexes {
-
- private int _lowIx;
- private int _highIx;
-
- public BinarySearchIndexes(int highIx) {
- _lowIx = -1;
- _highIx = highIx;
- }
-
- /**
- * @return -1 if the search range is empty
- */
- public int getMidIx() {
- int ixDiff = _highIx - _lowIx;
- if(ixDiff < 2) {
- return -1;
- }
- return _lowIx + (ixDiff / 2);
- }
-
- public int getLowIx() {
- return _lowIx;
- }
- public int getHighIx() {
- return _highIx;
- }
- public void narrowSearch(int midIx, boolean isLessThan) {
- if(isLessThan) {
- _highIx = midIx;
- } else {
- _lowIx = midIx;
- }
- }
- }
- /**
- * Excel has funny behaviour when the some elements in the search vector are the wrong type.
- *
- */
- private static int performBinarySearch(ValueVector vector, LookupValueComparer lookupComparer) {
- // both low and high indexes point to values assumed too low and too high.
- BinarySearchIndexes bsi = new BinarySearchIndexes(vector.getSize());
-
- while(true) {
- int midIx = bsi.getMidIx();
-
- if(midIx < 0) {
- return bsi.getLowIx();
- }
- CompareResult cr = lookupComparer.compareTo(vector.getItem(midIx));
- if(cr.isTypeMismatch()) {
- int newMidIx = handleMidValueTypeMismatch(lookupComparer, vector, bsi, midIx);
- if(newMidIx < 0) {
- continue;
- }
- midIx = newMidIx;
- cr = lookupComparer.compareTo(vector.getItem(midIx));
- }
- if(cr.isEqual()) {
- return findLastIndexInRunOfEqualValues(lookupComparer, vector, midIx, bsi.getHighIx());
- }
- bsi.narrowSearch(midIx, cr.isLessThan());
- }
- }
- /**
- * Excel seems to handle mismatched types initially by just stepping 'mid' ix forward to the
- * first compatible value.
- * @param midIx 'mid' index (value which has the wrong type)
- * @return usually -1, signifying that the BinarySearchIndex has been narrowed to the new mid
- * index. Zero or greater signifies that an exact match for the lookup value was found
- */
- private static int handleMidValueTypeMismatch(LookupValueComparer lookupComparer, ValueVector vector,
- BinarySearchIndexes bsi, int midIx) {
- int newMid = midIx;
- int highIx = bsi.getHighIx();
-
- while(true) {
- newMid++;
- if(newMid == highIx) {
- // every element from midIx to highIx was the wrong type
- // move highIx down to the low end of the mid values
- bsi.narrowSearch(midIx, true);
- return -1;
- }
- CompareResult cr = lookupComparer.compareTo(vector.getItem(newMid));
- if(cr.isLessThan() && newMid == highIx-1) {
- // move highIx down to the low end of the mid values
- bsi.narrowSearch(midIx, true);
- return -1;
- // but only when "newMid == highIx-1"? slightly weird.
- // It would seem more efficient to always do this.
- }
- if(cr.isTypeMismatch()) {
- // keep stepping over values until the right type is found
- continue;
- }
- if(cr.isEqual()) {
- return newMid;
- }
- // Note - if moving highIx down (due to lookupValue | Matching Behaviour |
---|---|
1 | (default) find the largest value that is less than or equal to lookup_value. - * The lookup_array must be in ascending order*. |
0 | find the first value that is exactly equal to lookup_value. - * The lookup_array can be in any order. |
-1 | find the smallest value that is greater than or equal to lookup_value. - * The lookup_array must be in descending order*. |
If n is negative, the resulting value is obtained - * as the round value of absolute value of n multiplied - * by the sign value of n (@see MathX.sign(double d)). - * Thus, -0.6666666 rounded to p=0 will give -1 not 0. - *
If n is NaN, returned value is NaN. - * @param n - * @param p - */ - public static double round(double n, int p) { - double retval; - - if (Double.isNaN(n) || Double.isInfinite(n)) { - retval = Double.NaN; - } - else { - if (p != 0) { - double temp = Math.pow(10, p); - retval = Math.round(n*temp)/temp; - } - else { - retval = Math.round(n); - } - } - - return retval; - } - - /** - * Returns a value rounded-up to p digits after decimal. - * If p is negative, then the number is rounded to - * places to the left of the decimal point. eg. - * 10.23 rounded to -1 will give: 20. If p is zero, - * the returned value is rounded to the nearest integral - * value. - *
If n is negative, the resulting value is obtained - * as the round-up value of absolute value of n multiplied - * by the sign value of n (@see MathX.sign(double d)). - * Thus, -0.2 rounded-up to p=0 will give -1 not 0. - *
If n is NaN, returned value is NaN. - * @param n - * @param p - */ - public static double roundUp(double n, int p) { - double retval; - - if (Double.isNaN(n) || Double.isInfinite(n)) { - retval = Double.NaN; - } - else { - if (p != 0) { - double temp = Math.pow(10, p); - double nat = Math.abs(n*temp); - - retval = sign(n) * - ((nat == (long) nat) - ? nat / temp - : Math.round(nat + 0.5) / temp); - } - else { - double na = Math.abs(n); - retval = sign(n) * - ((na == (long) na) - ? na - : (long) na + 1); - } - } - - return retval; - } - - /** - * Returns a value rounded to p digits after decimal. - * If p is negative, then the number is rounded to - * places to the left of the decimal point. eg. - * 10.23 rounded to -1 will give: 10. If p is zero, - * the returned value is rounded to the nearest integral - * value. - *
If n is negative, the resulting value is obtained - * as the round-up value of absolute value of n multiplied - * by the sign value of n (@see MathX.sign(double d)). - * Thus, -0.8 rounded-down to p=0 will give 0 not -1. - *
If n is NaN, returned value is NaN.
- * @param n
- * @param p
- */
- public static double roundDown(double n, int p) {
- double retval;
-
- if (Double.isNaN(n) || Double.isInfinite(n)) {
- retval = Double.NaN;
- }
- else {
- if (p != 0) {
- double temp = Math.pow(10, p);
- retval = sign(n) * Math.round((Math.abs(n)*temp) - 0.5)/temp;
- }
- else {
- retval = (long) n;
- }
- }
-
- return retval;
- }
-
-
- /**
- * If d < 0, returns short -1
- *
- * If d > 0, returns short 1
- *
- * If d == 0, returns short 0
- *
If d is NaN, then 1 will be returned. It is the responsibility
- * of caller to check for d isNaN if some other value is desired.
- * @param d
- */
- public static short sign(double d) {
- return (short) ((d == 0)
- ? 0
- : (d < 0)
- ? -1
- : 1);
- }
-
- /**
- * average of all values
- * @param values
- */
- public static double average(double[] values) {
- double ave = 0;
- double sum = 0;
- for (int i=0, iSize=values.length; i
- * When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s;
- *
- *
- * Syntax :
- * n and s are invalid if any of following conditions are true:
- *
- *
- * In all such cases, Double.NaN is returned.
- * @param n
- * @param s
- */
- public static double floor(double n, double s) {
- double f;
-
- if ((n<0 && s>0) || (n>0 && s<0) || (s==0 && n!=0)) {
- f = Double.NaN;
- }
- else {
- f = (n==0 || s==0) ? 0 : Math.floor(n/s) * s;
- }
-
- return f;
- }
-
- /**
- * Note: this function is different from java.lang.Math.ceil(..).
- *
- * n and s are invalid if any of following conditions are true:
- *
- *
- * In all such cases, Double.NaN is returned.
- * @param n
- * @param s
- */
- public static double ceiling(double n, double s) {
- double c;
-
- if ((n<0 && s>0) || (n>0 && s<0)) {
- c = Double.NaN;
- }
- else {
- c = (n == 0 || s == 0) ? 0 : Math.ceil(n/s) * s;
- }
-
- return c;
- }
-
- /**
- *
for all n >= 1; factorial n = n * (n-1) * (n-2) * ... * 1
- *
else if n == 0; factorial n = 1
- *
else if n < 0; factorial n = Double.NaN
- *
Loss of precision can occur if n is large enough.
- * If n is large so that the resulting value would be greater
- * than Double.MAX_VALUE; Double.POSITIVE_INFINITY is returned.
- * If n < 0, Double.NaN is returned.
- * @param n
- */
- public static double factorial(int n) {
- double d = 1;
-
- if (n >= 0) {
- if (n <= 170) {
- for (int i=1; i<=n; i++) {
- d *= i;
- }
- }
- else {
- d = Double.POSITIVE_INFINITY;
- }
- }
- else {
- d = Double.NaN;
- }
- return d;
- }
-
-
- /**
- * returns the remainder resulting from operation:
- * n / d.
- *
The result has the sign of the divisor.
- *
Examples:
- *
- *
- * If d == 0, result is NaN
- * @param n
- * @param d
- */
- public static double mod(double n, double d) {
- double result = 0;
-
- if (d == 0) {
- result = Double.NaN;
- }
- else if (sign(n) == sign(d)) {
- result = n % d;
- }
- else {
- result = ((n % d) + d) % d;
- }
-
- return result;
- }
-
- /**
- * inverse hyperbolic cosine
- * @param d
- */
- public static double acosh(double d) {
- return Math.log(Math.sqrt(Math.pow(d, 2) - 1) + d);
- }
-
- /**
- * inverse hyperbolic sine
- * @param d
- */
- public static double asinh(double d) {
- return Math.log(Math.sqrt(d*d + 1) + d);
- }
-
- /**
- * inverse hyperbolic tangent
- * @param d
- */
- public static double atanh(double d) {
- return Math.log((1 + d)/(1 - d)) / 2;
- }
-
- /**
- * hyperbolic cosine
- * @param d
- */
- public static double cosh(double d) {
- double ePowX = Math.pow(Math.E, d);
- double ePowNegX = Math.pow(Math.E, -d);
- return (ePowX + ePowNegX) / 2;
- }
-
- /**
- * hyperbolic sine
- * @param d
- */
- public static double sinh(double d) {
- double ePowX = Math.pow(Math.E, d);
- double ePowNegX = Math.pow(Math.E, -d);
- return (ePowX - ePowNegX) / 2;
- }
-
- /**
- * hyperbolic tangent
- * @param d
- */
- public static double tanh(double d) {
- double ePowX = Math.pow(Math.E, d);
- double ePowNegX = Math.pow(Math.E, -d);
- return (ePowX - ePowNegX) / (ePowX + ePowNegX);
- }
-
-
- /**
- * returns the total number of combinations possible when
- * k items are chosen out of total of n items. If the number
- * is too large, loss of precision may occur (since returned
- * value is double). If the returned value is larger than
- * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned.
- * If either of the parameters is negative, Double.NaN is returned.
- * @param n
- * @param k
- */
- public static double nChooseK(int n, int k) {
- double d = 1;
- if (n<0 || k<0 || nnull
.
- *
- * @return never null
- */
- protected final double[] getNumberArray(ValueEval[] operands) throws EvaluationException {
- if (operands.length > getMaxNumOperands()) {
- throw EvaluationException.invalidValue();
- }
- DoubleList retval = new DoubleList();
-
- for (int i=0, iSize=operands.length; i
- * OFFSET(reference, rows, cols, height, width)
- * reference is the base reference.
- * rows is the number of rows up or down from the base reference.
- * cols is the number of columns left or right from the base reference.
- * height (default same height as base reference) is the row count for the returned area reference.
- * width (default same width as base reference) is the column count for the returned area reference.
- *
- * @author Josh Micich
- */
-public final class Offset implements Function {
- // These values are specific to BIFF8
- private static final int LAST_VALID_ROW_INDEX = 0xFFFF;
- private static final int LAST_VALID_COLUMN_INDEX = 0xFF;
-
-
- /**
- * A one dimensional base + offset. Represents either a row range or a column range.
- * Two instances of this class together specify an area range.
- */
- /* package */ static final class LinearOffsetRange {
-
- private final int _offset;
- private final int _length;
-
- public LinearOffsetRange(int offset, int length) {
- if(length == 0) {
- // handled that condition much earlier
- throw new RuntimeException("length may not be zero");
- }
- _offset = offset;
- _length = length;
- }
-
- public short getFirstIndex() {
- return (short) _offset;
- }
- public short getLastIndex() {
- return (short) (_offset + _length - 1);
- }
- /**
- * Moves the range by the specified translation amount.
- *
- * This method also 'normalises' the range: Excel specifies that the width and height
- * parameters (length field here) cannot be negative. However, OFFSET() does produce
- * sensible results in these cases. That behavior is replicated here.
- *
- * @param translationAmount may be zero negative or positive
- *
- * @return the equivalent LinearOffsetRange with a positive length, moved by the
- * specified translationAmount.
- */
- public LinearOffsetRange normaliseAndTranslate(int translationAmount) {
- if (_length > 0) {
- if(translationAmount == 0) {
- return this;
- }
- return new LinearOffsetRange(translationAmount + _offset, _length);
- }
- return new LinearOffsetRange(translationAmount + _offset + _length + 1, -_length);
- }
-
- public boolean isOutOfBounds(int lowValidIx, int highValidIx) {
- if(_offset < lowValidIx) {
- return true;
- }
- if(getLastIndex() > highValidIx) {
- return true;
- }
- return false;
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(_offset).append("...").append(getLastIndex());
- sb.append("]");
- return sb.toString();
- }
- }
-
- /**
- * Encapsulates either an area or cell reference which may be 2d or 3d.
- */
- private static final class BaseRef {
- private final int _firstRowIndex;
- private final int _firstColumnIndex;
- private final int _width;
- private final int _height;
- private final RefEval _refEval;
- private final AreaEval _areaEval;
-
- public BaseRef(RefEval re) {
- _refEval = re;
- _areaEval = null;
- _firstRowIndex = re.getRow();
- _firstColumnIndex = re.getColumn();
- _height = 1;
- _width = 1;
- }
-
- public BaseRef(AreaEval ae) {
- _refEval = null;
- _areaEval = ae;
- _firstRowIndex = ae.getFirstRow();
- _firstColumnIndex = ae.getFirstColumn();
- _height = ae.getLastRow() - ae.getFirstRow() + 1;
- _width = ae.getLastColumn() - ae.getFirstColumn() + 1;
- }
-
- public int getWidth() {
- return _width;
- }
- public int getHeight() {
- return _height;
- }
- public int getFirstRowIndex() {
- return _firstRowIndex;
- }
- public int getFirstColumnIndex() {
- return _firstColumnIndex;
- }
-
- public AreaEval offset(int relFirstRowIx, int relLastRowIx,
- int relFirstColIx, int relLastColIx) {
- if (_refEval == null) {
- return _areaEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
- }
- return _refEval.offset(relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
- }
- }
-
- public ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {
- if(args.length < 3 || args.length > 5) {
- return ErrorEval.VALUE_INVALID;
- }
-
- try {
- BaseRef baseRef = evaluateBaseRef(args[0]);
- int rowOffset = evaluateIntArg(args[1], srcCellRow, srcCellCol);
- int columnOffset = evaluateIntArg(args[2], srcCellRow, srcCellCol);
- int height = baseRef.getHeight();
- int width = baseRef.getWidth();
- switch(args.length) {
- case 5:
- width = evaluateIntArg(args[4], srcCellRow, srcCellCol);
- case 4:
- height = evaluateIntArg(args[3], srcCellRow, srcCellCol);
- }
- // Zero height or width raises #REF! error
- if(height == 0 || width == 0) {
- return ErrorEval.REF_INVALID;
- }
- LinearOffsetRange rowOffsetRange = new LinearOffsetRange(rowOffset, height);
- LinearOffsetRange colOffsetRange = new LinearOffsetRange(columnOffset, width);
- return createOffset(baseRef, rowOffsetRange, colOffsetRange);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- }
-
- private static AreaEval createOffset(BaseRef baseRef,
- LinearOffsetRange orRow, LinearOffsetRange orCol) throws EvaluationException {
- LinearOffsetRange absRows = orRow.normaliseAndTranslate(baseRef.getFirstRowIndex());
- LinearOffsetRange absCols = orCol.normaliseAndTranslate(baseRef.getFirstColumnIndex());
-
- if(absRows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) {
- throw new EvaluationException(ErrorEval.REF_INVALID);
- }
- if(absCols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) {
- throw new EvaluationException(ErrorEval.REF_INVALID);
- }
- return baseRef.offset(orRow.getFirstIndex(), orRow.getLastIndex(), orCol.getFirstIndex(), orCol.getLastIndex());
- }
-
- private static BaseRef evaluateBaseRef(ValueEval eval) throws EvaluationException {
-
- if(eval instanceof RefEval) {
- return new BaseRef((RefEval)eval);
- }
- if(eval instanceof AreaEval) {
- return new BaseRef((AreaEval)eval);
- }
- if (eval instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) eval);
- }
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
-
- /**
- * OFFSET's numeric arguments (2..5) have similar processing rules
- */
- static int evaluateIntArg(ValueEval eval, int srcCellRow, int srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(eval, srcCellRow, srcCellCol);
- return OperandResolver.coerceValueToInt(ve);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Replace.java b/src/java/org/apache/poi/hssf/record/formula/functions/Replace.java
deleted file mode 100644
index f2af838f91..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Replace.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.
-==================================================================== */
-
-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.EvaluationException;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * An implementation of the Excel REPLACE() function:
- * Replaces part of a text string based on the number of characters
- * you specify, with another text string.
- *
- * Syntax:
- * REPLACE(oldText, startNum, numChars, newText)
- *
- * oldText The text string containing characters to replace
- * startNum The position of the first character to replace (1-based)
- * numChars The number of characters to replace
- * newText The new text value to replace the removed section
- *
- * @author Manda Wilson < wilson at c bio dot msk cc dot org >
- */
-public final class Replace extends Fixed4ArgFunction {
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2, ValueEval arg3) {
-
- String oldStr;
- int startNum;
- int numChars;
- String newStr;
- try {
- oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
- startNum = TextFunction.evaluateIntArg(arg1, srcRowIndex, srcColumnIndex);
- numChars = TextFunction.evaluateIntArg(arg2, srcRowIndex, srcColumnIndex);
- newStr = TextFunction.evaluateStringArg(arg3, srcRowIndex, srcColumnIndex);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
-
- if (startNum < 1 || numChars < 0) {
- return ErrorEval.VALUE_INVALID;
- }
- StringBuffer strBuff = new StringBuffer(oldStr);
- // remove any characters that should be replaced
- if (startNum <= oldStr.length() && numChars != 0) {
- strBuff.delete(startNum - 1, startNum - 1 + numChars);
- }
- // now insert (or append) newStr
- if (startNum > strBuff.length()) {
- strBuff.append(newStr);
- } else {
- strBuff.insert(startNum - 1, newStr);
- }
- return new StringEval(strBuff.toString());
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/RowFunc.java b/src/java/org/apache/poi/hssf/record/formula/functions/RowFunc.java
deleted file mode 100644
index ea1aa3252f..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/RowFunc.java
+++ /dev/null
@@ -1,59 +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.record.formula.eval.AreaEval;
-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.RefEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * Implementation for the Excel function ROW
- *
- * @author Josh Micich
- */
-public final class RowFunc implements Function0Arg, Function1Arg {
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
- return new NumberEval(srcRowIndex+1);
- }
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
- int rnum;
-
- if (arg0 instanceof AreaEval) {
- rnum = ((AreaEval) arg0).getFirstRow();
- } else if (arg0 instanceof RefEval) {
- rnum = ((RefEval) arg0).getRow();
- } else {
- // anything else is not valid argument
- return ErrorEval.VALUE_INVALID;
- }
-
- return new NumberEval(rnum + 1);
- }
- public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- switch (args.length) {
- case 1:
- return evaluate(srcRowIndex, srcColumnIndex, args[0]);
- case 0:
- return new NumberEval(srcRowIndex+1);
- }
- return ErrorEval.VALUE_INVALID;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java
deleted file mode 100644
index 91da8e157d..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java
+++ /dev/null
@@ -1,45 +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.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.RefEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.TwoDEval;
-
-/**
- * Implementation for Excel ROWS function.
- *
- * @author Josh Micich
- */
-public final class Rows extends Fixed1ArgFunction {
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
-
- int result;
- if (arg0 instanceof TwoDEval) {
- result = ((TwoDEval) arg0).getHeight();
- } else if (arg0 instanceof RefEval) {
- result = 1;
- } else { // anything else is not valid argument
- return ErrorEval.VALUE_INVALID;
- }
- return new NumberEval(result);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/StatsLib.java b/src/java/org/apache/poi/hssf/record/formula/functions/StatsLib.java
deleted file mode 100644
index 2cc4a78f37..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/StatsLib.java
+++ /dev/null
@@ -1,137 +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 java.util.Arrays;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- * Library for common statistics functions
- */
-final class StatsLib {
-
- private StatsLib() {
- // no instances of this class
- }
-
-
- /**
- * returns the mean of deviations from mean.
- * @param v
- */
- public static double avedev(double[] v) {
- double r = 0;
- double m = 0;
- double s = 0;
- for (int i=0, iSize=v.length; i
- * k <= 0 & k >= v.length or null array or empty array
- * will result in return value Double.NaN
- * @param v
- * @param k
- */
- public static double kthSmallest(double[] v, int k) {
- double r = Double.NaN;
- int index = k-1; // since arrays are 0-based
- if (v!=null && v.length > index && index >= 0) {
- Arrays.sort(v);
- r = v[index];
- }
- return r;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Substitute.java b/src/java/org/apache/poi/hssf/record/formula/functions/Substitute.java
deleted file mode 100644
index 558de6ba8f..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Substitute.java
+++ /dev/null
@@ -1,108 +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.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.EvaluationException;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * An implementation of the SUBSTITUTE function:
- * Substitutes text in a text string with new text, some number of times.
- * @author Manda Wilson < wilson at c bio dot msk cc dot org >
- */
-public final class Substitute extends Var3or4ArgFunction {
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2) {
- String result;
- try {
- String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
- String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
- String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex);
-
- result = replaceAllOccurrences(oldStr, searchStr, newStr);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new StringEval(result);
- }
-
- public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1,
- ValueEval arg2, ValueEval arg3) {
- String result;
- try {
- String oldStr = TextFunction.evaluateStringArg(arg0, srcRowIndex, srcColumnIndex);
- String searchStr = TextFunction.evaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
- String newStr = TextFunction.evaluateStringArg(arg2, srcRowIndex, srcColumnIndex);
-
- int instanceNumber = TextFunction.evaluateIntArg(arg3, srcRowIndex, srcColumnIndex);
- if (instanceNumber < 1) {
- return ErrorEval.VALUE_INVALID;
- }
- result = replaceOneOccurrence(oldStr, searchStr, newStr, instanceNumber);
- } catch (EvaluationException e) {
- return e.getErrorEval();
- }
- return new StringEval(result);
- }
-
- private static String replaceAllOccurrences(String oldStr, String searchStr, String newStr) {
- StringBuffer sb = new StringBuffer();
- int startIndex = 0;
- int nextMatch = -1;
- while (true) {
- nextMatch = oldStr.indexOf(searchStr, startIndex);
- if (nextMatch < 0) {
- // store everything from end of last match to end of string
- sb.append(oldStr.substring(startIndex));
- return sb.toString();
- }
- // store everything from end of last match to start of this match
- sb.append(oldStr.substring(startIndex, nextMatch));
- sb.append(newStr);
- startIndex = nextMatch + searchStr.length();
- }
- }
-
- private static String replaceOneOccurrence(String oldStr, String searchStr, String newStr, int instanceNumber) {
- if (searchStr.length() < 1) {
- return oldStr;
- }
- int startIndex = 0;
- int nextMatch = -1;
- int count=0;
- while (true) {
- nextMatch = oldStr.indexOf(searchStr, startIndex);
- if (nextMatch < 0) {
- // not enough occurrences found - leave unchanged
- return oldStr;
- }
- count++;
- if (count == instanceNumber) {
- StringBuffer sb = new StringBuffer(oldStr.length() + newStr.length());
- sb.append(oldStr.substring(0, nextMatch));
- sb.append(newStr);
- sb.append(oldStr.substring(nextMatch + searchStr.length()));
- return sb.toString();
- }
- startIndex = nextMatch + searchStr.length();
- }
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Subtotal.java b/src/java/org/apache/poi/hssf/record/formula/functions/Subtotal.java
deleted file mode 100644
index cdf74f820f..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Subtotal.java
+++ /dev/null
@@ -1,100 +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.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.EvaluationException;
-import org.apache.poi.hssf.record.formula.eval.OperandResolver;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.ss.formula.eval.NotImplementedException;
-
-/**
- * Implementation for the Excel function SUBTOTAL
- * SUBTOTAL ( functionCode, ref1, ref2 ... )
- *
- *
- * functionCode (1-11) Selects the underlying aggregate function to be used (see table below)
- * ref1, ref2 ... Arguments to be passed to the underlying aggregate function
- *
functionCode | Aggregate Function |
---|---|
1 | AVERAGE |
2 | COUNT |
3 | COUNTA |
4 | MAX |
5 | MIN |
6 | PRODUCT |
7 | STDEV |
8 | STDEVP * |
9 | AVERAGE |
10 | VAR * |
11 | VARP * |
101-111 | * |
- *
- * Syntax :
- * SUMIF ( range, criteria, sum_range )
- *
range | The range over which criteria is applied. Also used for addend values when the third parameter is not present |
---|---|
criteria | The value or expression used to filter rows from range |
sum_range | Locates the top-left corner of the corresponding range of addends - values to be added (after being selected by the criteria) |
array1, ... arrayN | typically area references, - * possibly cell references or scalar values |
---|
ValueEval
.
- * @param isScalarProduct false
for SUMPRODUCTs over area refs.
- * @throws EvaluationException if ve
represents an error value.
- *
- * Note - string values and empty cells are interpreted differently depending on
- * isScalarProduct
. For scalar products, if any term is blank or a string, the
- * error (#VALUE!) is raised. For area (sum)products, if any term is blank or a string, the
- * result is zero.
- */
- private static double getProductTerm(ValueEval ve, boolean isScalarProduct) throws EvaluationException {
-
- if(ve instanceof BlankEval || ve == null) {
- // TODO - shouldn't BlankEval.INSTANCE be used always instead of null?
- // null seems to occur when the blank cell is part of an area ref (but not reliably)
- if(isScalarProduct) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- return 0;
- }
-
- if(ve instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval)ve);
- }
- if(ve instanceof StringEval) {
- if(isScalarProduct) {
- throw new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- // Note for area SUMPRODUCTs, string values are interpreted as zero
- // even if they would parse as valid numeric values
- return 0;
- }
- if(ve instanceof NumericValueEval) {
- NumericValueEval nve = (NumericValueEval) ve;
- return nve.getNumberValue();
- }
- throw new RuntimeException("Unexpected value eval class ("
- + ve.getClass().getName() + ")");
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java
deleted file mode 100644
index b271169666..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java
+++ /dev/null
@@ -1,43 +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;
-
-
-/**
- * Implementation of Excel function SUMX2MY2()
- *
- * Calculates the sum of differences of squares in two arrays of the same size.null
if there is any problem converting the text
- */
- private static Double convertTextToNumber(String strText) {
- boolean foundCurrency = false;
- boolean foundUnaryPlus = false;
- boolean foundUnaryMinus = false;
-
- int len = strText.length();
- int i;
- for (i = 0; i < len; i++) {
- char ch = strText.charAt(i);
- if (Character.isDigit(ch) || ch == '.') {
- break;
- }
- switch (ch) {
- case ' ':
- // intervening spaces between '$', '-', '+' are OK
- continue;
- case '$':
- if (foundCurrency) {
- // only one currency symbols is allowed
- return null;
- }
- foundCurrency = true;
- continue;
- case '+':
- if (foundUnaryMinus || foundUnaryPlus) {
- return null;
- }
- foundUnaryPlus = true;
- continue;
- case '-':
- if (foundUnaryMinus || foundUnaryPlus) {
- return null;
- }
- foundUnaryMinus = true;
- continue;
- default:
- // all other characters are illegal
- return null;
- }
- }
- if (i >= len) {
- // didn't find digits or '.'
- if (foundCurrency || foundUnaryMinus || foundUnaryPlus) {
- return null;
- }
- return ZERO;
- }
-
- // remove thousands separators
-
- boolean foundDecimalPoint = false;
- int lastThousandsSeparatorIndex = Short.MIN_VALUE;
-
- StringBuffer sb = new StringBuffer(len);
- for (; i < len; i++) {
- char ch = strText.charAt(i);
- if (Character.isDigit(ch)) {
- sb.append(ch);
- continue;
- }
- switch (ch) {
- case ' ':
- String remainingText = strText.substring(i);
- if (remainingText.trim().length() > 0) {
- // intervening spaces not allowed once the digits start
- return null;
- }
- break;
- case '.':
- if (foundDecimalPoint) {
- return null;
- }
- if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) {
- return null;
- }
- foundDecimalPoint = true;
- sb.append('.');
- continue;
- case ',':
- if (foundDecimalPoint) {
- // thousands separators not allowed after '.' or 'E'
- return null;
- }
- int distanceBetweenThousandsSeparators = i - lastThousandsSeparatorIndex;
- // as long as there are 3 or more digits between
- if (distanceBetweenThousandsSeparators < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) {
- return null;
- }
- lastThousandsSeparatorIndex = i;
- // don't append ','
- continue;
-
- case 'E':
- case 'e':
- if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) {
- return null;
- }
- // append rest of strText and skip to end of loop
- sb.append(strText.substring(i));
- i = len;
- break;
- default:
- // all other characters are illegal
- return null;
- }
- }
- if (!foundDecimalPoint) {
- if (i - lastThousandsSeparatorIndex < MIN_DISTANCE_BETWEEN_THOUSANDS_SEPARATOR) {
- return null;
- }
- }
- double d;
- try {
- d = Double.parseDouble(sb.toString());
- } catch (NumberFormatException e) {
- // still a problem parsing the number - probably out of range
- return null;
- }
- return new Double(foundUnaryMinus ? -d : d);
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Var1or2ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Var1or2ArgFunction.java
deleted file mode 100644
index d7310c41bf..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Var1or2ArgFunction.java
+++ /dev/null
@@ -1,40 +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.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * Convenience base class for any function which must take two or three
- * arguments
- *
- * @author Josh Micich
- */
-abstract class Var1or2ArgFunction implements Function1Arg, Function2Arg {
-
- public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- switch (args.length) {
- case 1:
- return evaluate(srcRowIndex, srcColumnIndex, args[0]);
- case 2:
- return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]);
- }
- return ErrorEval.VALUE_INVALID;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Var2or3ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Var2or3ArgFunction.java
deleted file mode 100644
index 4928425f99..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Var2or3ArgFunction.java
+++ /dev/null
@@ -1,40 +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.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * Convenience base class for any function which must take two or three
- * arguments
- *
- * @author Josh Micich
- */
-abstract class Var2or3ArgFunction implements Function2Arg, Function3Arg {
-
- public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- switch (args.length) {
- case 2:
- return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1]);
- case 3:
- return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]);
- }
- return ErrorEval.VALUE_INVALID;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Var3or4ArgFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/Var3or4ArgFunction.java
deleted file mode 100644
index c3cf9410a4..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Var3or4ArgFunction.java
+++ /dev/null
@@ -1,40 +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.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * Convenience base class for any function which must take three or four
- * arguments
- *
- * @author Josh Micich
- */
-abstract class Var3or4ArgFunction implements Function3Arg, Function4Arg {
-
- public final ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
- switch (args.length) {
- case 3:
- return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2]);
- case 4:
- return evaluate(srcRowIndex, srcColumnIndex, args[0], args[1], args[2], args[3]);
- }
- return ErrorEval.VALUE_INVALID;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java b/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java
deleted file mode 100644
index 1e240eb886..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java
+++ /dev/null
@@ -1,81 +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.record.formula.eval.BoolEval;
-import org.apache.poi.hssf.record.formula.eval.EvaluationException;
-import org.apache.poi.hssf.record.formula.eval.OperandResolver;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.functions.LookupUtils.ValueVector;
-import org.apache.poi.ss.formula.TwoDEval;
-/**
- * Implementation of the VLOOKUP() function.
- *
- * VLOOKUP finds a row in a lookup table by the first column value and returns the value from another column.null
if
- * function isn't contained by any registered tool pack.
- *
- * @param name Name of function.
- * @return Function executor. null
if not found
- */
- public FreeRefFunction findFunction(String name) {
- FreeRefFunction evaluatorForFunction;
- for (UDFFinder pack : _usedToolPacks) {
- evaluatorForFunction = pack.findFunction(name);
- if (evaluatorForFunction != null) {
- return evaluatorForFunction;
- }
- }
- return null;
- }
-}
diff --git a/src/java/org/apache/poi/hssf/record/formula/udf/DefaultUDFFinder.java b/src/java/org/apache/poi/hssf/record/formula/udf/DefaultUDFFinder.java
deleted file mode 100644
index f87027aeb7..0000000000
--- a/src/java/org/apache/poi/hssf/record/formula/udf/DefaultUDFFinder.java
+++ /dev/null
@@ -1,49 +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.udf;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-
-/**
- * Default UDF finder - for adding your own user defined functions.
- *
- * @author PUdalau
- */
-public final class DefaultUDFFinder implements UDFFinder {
- private final Mapnull
if the function name is unknown.
- *
- * @param name Name of function.
- * @return Function executor.
- */
- FreeRefFunction findFunction(String name);
-}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
index 2862a0d032..63d42a639e 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
@@ -29,7 +29,6 @@ import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.DrawingRecord;
-import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.HyperlinkRecord;
@@ -45,7 +44,7 @@ import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.common.UnicodeString;
import org.apache.poi.hssf.record.formula.ExpPtg;
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
index 4242602c66..0250619c3d 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
@@ -19,12 +19,12 @@ package org.apache.poi.hssf.usermodel;
import java.util.Iterator;
-import org.apache.poi.hssf.record.formula.eval.BoolEval;
-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.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.record.formula.udf.UDFFinder;
+import org.apache.poi.ss.formula.eval.BoolEval;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.NumberEval;
+import org.apache.poi.ss.formula.eval.StringEval;
+import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.udf.UDFFinder;
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment;
import org.apache.poi.ss.formula.IStabilityClassifier;
import org.apache.poi.ss.formula.WorkbookEvaluator;
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index 96166d6a4c..9b39c665a1 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -17,14 +17,7 @@
package org.apache.poi.hssf.usermodel;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextLayout;
-import java.awt.geom.AffineTransform;
import java.io.PrintWriter;
-import java.text.AttributedString;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -38,7 +31,7 @@ import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock;
-import org.apache.poi.hssf.record.formula.FormulaShifter;
+import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.util.PaneInformation;
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
index 7cedfecacd..b999512b22 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
@@ -61,7 +61,7 @@ import org.apache.poi.hssf.record.formula.NameXPtg;
import org.apache.poi.hssf.record.formula.OperandPtg;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.record.formula.Ref3DPtg;
-import org.apache.poi.hssf.record.formula.SheetNameFormatter;
+import org.apache.poi.ss.formula.SheetNameFormatter;
import org.apache.poi.hssf.record.formula.UnionPtg;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.poifs.filesystem.DirectoryNode;
--
2.39.5