From: Nick Burch Date: Sat, 29 Mar 2008 19:36:53 +0000 (+0000) Subject: Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-63924... X-Git-Tag: REL_3_5_BETA2~160 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4bc2e0eb3e2c448ef5e47e2bff8866d1f2670c5b;p=poi.git Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642566,642568-642574,642576 via svnmerge from https://svn.apache.org/repos/asf/poi/trunk ........ r642566 | nick | 2008-03-29 17:45:28 +0000 (Sat, 29 Mar 2008) | 1 line Move the missing record aware eventusermodel code out of scratchpad ........ r642571 | nick | 2008-03-29 18:11:48 +0000 (Sat, 29 Mar 2008) | 1 line Merge several bug tests into one file ........ r642574 | nick | 2008-03-29 18:23:33 +0000 (Sat, 29 Mar 2008) | 1 line Move the FormulaEvaluator code out of scratchpad ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@642591 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/build.xml b/build.xml index 75801a4698..523e328bef 100644 --- a/build.xml +++ b/build.xml @@ -240,10 +240,10 @@ under the License. - - - - + + + + @@ -449,7 +449,7 @@ under the License. fork="yes" srcdir="${main.src.test}"> - + @@ -478,7 +478,7 @@ under the License. fork="yes" srcdir="${scratchpad.src.test}"> - + @@ -512,19 +512,20 @@ under the License. fork="yes" srcdir="${contrib.src.test}"> - + - + + failonerror="true" destdir="${examples.output.dir}" debug="on" fork="yes" + srcdir="${examples.src}"> - + @@ -542,7 +543,7 @@ under the License. fork="yes" srcdir="${ooxml.src.test}"> - + diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 1aca38e385..ab9a4c796e 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -35,7 +35,9 @@ - + + Move the Formula Evaluator code out of scratchpad + Move the missing record aware eventusermodel code out of scratchpad 44652 / 44603 - Improved handling of Pictures in Word Documents 44636 - Fix formula parsing of RefVPtg, which was causing #VALUE to be shown on subsequent edits 44627 - Improve the thread safety of POILogFactory diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 6b55026c78..14c7b817a1 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -32,7 +32,9 @@ - + + Move the Formula Evaluator code out of scratchpad + Move the missing record aware eventusermodel code out of scratchpad 44652 / 44603 - Improved handling of Pictures in Word Documents 44636 - Fix formula parsing of RefVPtg, which was causing #VALUE to be shown on subsequent edits 44627 - Improve the thread safety of POILogFactory diff --git a/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java b/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java new file mode 100644 index 0000000000..a727d064b9 --- /dev/null +++ b/src/java/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java @@ -0,0 +1,203 @@ +/* ==================================================================== + 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.eventusermodel; + +import org.apache.poi.hssf.eventusermodel.HSSFListener; +import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; +import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; +import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord; +import org.apache.poi.hssf.record.BOFRecord; +import org.apache.poi.hssf.record.BlankRecord; +import org.apache.poi.hssf.record.BoolErrRecord; +import org.apache.poi.hssf.record.BoundSheetRecord; +import org.apache.poi.hssf.record.FormulaRecord; +import org.apache.poi.hssf.record.LabelRecord; +import org.apache.poi.hssf.record.LabelSSTRecord; +import org.apache.poi.hssf.record.NoteRecord; +import org.apache.poi.hssf.record.NumberRecord; +import org.apache.poi.hssf.record.RKRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RowRecord; + +/** + *

A HSSFListener which tracks rows and columns, and will + * trigger your HSSFListener for all rows and cells, + * even the ones that aren't actually stored in the file.

+ *

This allows your code to have a more "Excel" like + * view of the data in the file, and not have to worry + * (as much) about if a particular row/cell is in the + * file, or was skipped from being written as it was + * blank. + */ +public class MissingRecordAwareHSSFListener implements HSSFListener { + private HSSFListener childListener; + private int lastSeenRow = -1; + private int lastSeenColumn = -1; + + /** + * Constructs a new MissingRecordAwareHSSFListener, which + * will fire processRecord on the supplied child + * HSSFListener for all Records, and missing records. + * @param listener The HSSFListener to pass records on to + */ + public MissingRecordAwareHSSFListener(HSSFListener listener) { + childListener = listener; + } + + public void processRecord(Record record) { + int thisRow = -1; + int thisColumn = -1; + + switch (record.getSid()) + { + // the BOFRecord can represent either the beginning of a sheet or the workbook + case BOFRecord.sid: + BOFRecord bof = (BOFRecord) record; + if (bof.getType() == bof.TYPE_WORKBOOK) + { + // Reset the row and column counts - new workbook + lastSeenRow = -1; + lastSeenColumn = -1; + //System.out.println("Encountered workbook"); + } else if (bof.getType() == bof.TYPE_WORKSHEET) + { + // Reset the row and column counts - new sheet + lastSeenRow = -1; + lastSeenColumn = -1; + //System.out.println("Encountered sheet reference"); + } + break; + case BoundSheetRecord.sid: + BoundSheetRecord bsr = (BoundSheetRecord) record; + //System.out.println("New sheet named: " + bsr.getSheetname()); + break; + case RowRecord.sid: + RowRecord rowrec = (RowRecord) record; + //System.out.println("Row " + rowrec.getRowNumber() + " found, first column at " + // + rowrec.getFirstCol() + " last column at " + rowrec.getLastCol()); + + // If there's a jump in rows, fire off missing row records + if(lastSeenRow+1 < rowrec.getRowNumber()) { + for(int i=(lastSeenRow+1); i + *

  • 1+TRUE = 2 + *
  • 1+FALSE = 1 + *
  • 1+"true" = #VALUE! + *
  • 1+"1" = 2 + *
  • 1+A1 = #VALUE if A1 contains "1" + *
  • 1+A1 = 2 if A1 contains ="1" + *
  • 1+A1 = 2 if A1 contains TRUE or =TRUE + *
  • 1+A1 = #VALUE! if A1 contains "TRUE" or ="TRUE" + */ +public class AddEval extends NumericOperationEval { + + private AddPtg delegate; + private static final ValueEvalToNumericXlator NUM_XLATOR = + new ValueEvalToNumericXlator((short) + ( ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + )); + + public AddEval(Ptg ptg) { + delegate = (AddPtg) ptg; + } + + public ValueEvalToNumericXlator getXlator() { + return NUM_XLATOR; + } + + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if(args.length != 2) { + return ErrorEval.VALUE_INVALID; + } + + double d = 0; + for (int i = 0; i < 2; i++) { + ValueEval ve = singleOperandEvaluate(args[i], srcRow, srcCol); + if(ve instanceof ErrorEval) { + return ve; + } + if (ve instanceof NumericValueEval) { + d += ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + return ErrorEval.VALUE_INVALID; + } + } + if(Double.isNaN(d) || Double.isInfinite(d)) { + return ErrorEval.NUM_ERROR; + } + return new NumberEval(d); + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java new file mode 100644 index 0000000000..4b9a64c1c0 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Area2DEval.java @@ -0,0 +1,100 @@ +/* +* 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.AreaPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class Area2DEval implements AreaEval { +// TODO -refactor with Area3DEval + private final AreaPtg _delegate; + + private final ValueEval[] _values; + + public Area2DEval(Ptg ptg, ValueEval[] values) { + if(ptg == null) { + throw new IllegalArgumentException("ptg must not be null"); + } + if(values == null) { + throw new IllegalArgumentException("values must not be null"); + } + for(int i=values.length-1; i>=0; i--) { + if(values[i] == null) { + throw new IllegalArgumentException("value array elements must not be null"); + } + } + // TODO - check size of array vs size of AreaPtg + _delegate = (AreaPtg) ptg; + _values = values; + } + + public int getFirstColumn() { + return _delegate.getFirstColumn(); + } + + public int getFirstRow() { + return _delegate.getFirstRow(); + } + + public int getLastColumn() { + return _delegate.getLastColumn(); + } + + public int getLastRow() { + return _delegate.getLastRow(); + } + + public ValueEval[] getValues() { + return _values; + } + + public ValueEval getValueAt(int row, int col) { + ValueEval retval; + int index = ((row-getFirstRow())*(getLastColumn()-getFirstColumn()+1))+(col-getFirstColumn()); + if (index <0 || index >= _values.length) + retval = ErrorEval.VALUE_INVALID; + else + retval = _values[index]; + return retval; + } + + public boolean contains(int row, int col) { + return (getFirstRow() <= row) && (getLastRow() >= row) + && (getFirstColumn() <= col) && (getLastColumn() >= col); + } + + public boolean containsRow(int row) { + return (getFirstRow() <= row) && (getLastRow() >= row); + } + + public boolean containsColumn(short col) { + return (getFirstColumn() <= col) && (getLastColumn() >= col); + } + + public boolean isColumn() { + return _delegate.getFirstColumn() == _delegate.getLastColumn(); + } + + public boolean isRow() { + return _delegate.getFirstRow() == _delegate.getLastRow(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java new file mode 100644 index 0000000000..2f539142d1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Area3DEval.java @@ -0,0 +1,105 @@ +/* +* 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.Area3DPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class Area3DEval implements AreaEval { + // TODO -refactor with Area3DEval + private final Area3DPtg _delegate; + + private final ValueEval[] _values; + + public Area3DEval(Ptg ptg, ValueEval[] values) { + if(ptg == null) { + throw new IllegalArgumentException("ptg must not be null"); + } + if(values == null) { + throw new IllegalArgumentException("values must not be null"); + } + for(int i=values.length-1; i>=0; i--) { + if(values[i] == null) { + throw new IllegalArgumentException("value array elements must not be null"); + } + } + // TODO - check size of array vs size of AreaPtg + _values = values; + _delegate = (Area3DPtg) ptg; + } + + public int getFirstColumn() { + return _delegate.getFirstColumn(); + } + + public int getFirstRow() { + return _delegate.getFirstRow(); + } + + public int getLastColumn() { + return (short) _delegate.getLastColumn(); + } + + public int getLastRow() { + return _delegate.getLastRow(); + } + + public ValueEval[] getValues() { + return _values; + } + + public ValueEval getValueAt(int row, int col) { + ValueEval retval; + int index = (row-getFirstRow())*(col-getFirstColumn()); + if (index <0 || index >= _values.length) + retval = ErrorEval.VALUE_INVALID; + else + retval = _values[index]; + return retval; + } + + public boolean contains(int row, int col) { + return (getFirstRow() <= row) && (getLastRow() >= row) + && (getFirstColumn() <= col) && (getLastColumn() >= col); + } + + public boolean containsRow(int row) { + return (getFirstRow() <= row) && (getLastRow() >= row); + } + + public boolean containsColumn(short col) { + return (getFirstColumn() <= col) && (getLastColumn() >= col); + } + + + public boolean isColumn() { + return _delegate.getFirstColumn() == _delegate.getLastColumn(); + } + + public boolean isRow() { + return _delegate.getFirstRow() == _delegate.getLastRow(); + } + + public int getExternSheetIndex() { + return _delegate.getExternSheetIndex(); + } +} 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 new file mode 100644 index 0000000000..82cc8a9b40 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/AreaEval.java @@ -0,0 +1,105 @@ +/* +* 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 AreaEval extends ValueEval { + + /** + * returns the 0-based index of the first row in + * this area. + */ + public int getFirstRow(); + + /** + * returns the 0-based index of the last row in + * this area. + */ + public int getLastRow(); + + /** + * returns the 0-based index of the first col in + * this area. + */ + public int getFirstColumn(); + + /** + * returns the 0-based index of the last col in + * this area. + */ + public int getLastColumn(); + + /** + * returns true if the Area's start and end row indexes + * are same. This result of this method should agree + * with getFirstRow() == getLastRow(). + */ + public boolean isRow(); + + /** + * returns true if the Area's start and end col indexes + * are same. This result of this method should agree + * with getFirstColumn() == getLastColumn(). + */ + public boolean isColumn(); + + /** + * The array of values in this area. Although the area + * maybe 1D (ie. isRow() or isColumn() returns true) or 2D + * the returned array is 1D. + */ + public ValueEval[] getValues(); + + /** + * returns the ValueEval from the values array at the specified + * row and col index. The specified indexes should be absolute indexes + * in the sheet and not relative indexes within the area. Also, + * if contains(row, col) evaluates to true, a null value will + * bre returned. + * @param row + * @param col + */ + public ValueEval getValueAt(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 + */ + public boolean contains(int row, int col); + + /** + * returns true if the specified col is in range + * @param col + */ + public boolean containsColumn(short col); + + /** + * returns true if the specified row is in range + * @param row + */ + public boolean containsRow(int row); +} 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 new file mode 100644 index 0000000000..df671821fe --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/BlankEval.java @@ -0,0 +1,33 @@ +/* +* 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 9, 2005 + * + */ +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 class BlankEval implements ValueEval { + + public static BlankEval INSTANCE = new BlankEval(); + + private BlankEval() { + } +} 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 new file mode 100644 index 0000000000..7b625aaa98 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/BoolEval.java @@ -0,0 +1,74 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 8, 2005 + * + */ +package org.apache.poi.hssf.record.formula.eval; + +import org.apache.poi.hssf.record.formula.BoolPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public 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 a BoolEval instance representing b. + */ + public static final BoolEval valueOf(boolean b) { + // TODO - find / replace all occurrences + return b ? TRUE : FALSE; + } + + public BoolEval(Ptg ptg) { + this.value = ((BoolPtg) ptg).getValue(); + } + + private BoolEval(boolean value) { + this.value = value; + } + + public boolean getBooleanValue() { + return value; + } + + public double getNumberValue() { + return value ? 1 : 0; + } + + public String getStringValue() { + return value ? "TRUE" : "FALSE"; + } + public 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/ConcatEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java new file mode 100644 index 0000000000..e54cd483f1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/ConcatEval.java @@ -0,0 +1,65 @@ +/* +* 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.ConcatPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class ConcatEval extends StringOperationEval { + + private ConcatPtg delegate; + + public ConcatEval(Ptg ptg) { + this.delegate = (ConcatPtg) ptg; + } + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if(args.length != 2) { + return ErrorEval.VALUE_INVALID; + } + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < 2; i++) { + + ValueEval ve = singleOperandEvaluate(args[i], srcRow, srcCol); + if (ve instanceof StringValueEval) { + StringValueEval sve = (StringValueEval) ve; + sb.append(sve.getStringValue()); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { // must be an error eval + return ve; + } + } + + return new StringEval(sb.toString()); + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/DivideEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/DivideEval.java new file mode 100644 index 0000000000..021168ad79 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/DivideEval.java @@ -0,0 +1,95 @@ +/* +* 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.DividePtg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class DivideEval extends NumericOperationEval { + + private DividePtg delegate; + + private static final ValueEvalToNumericXlator NUM_XLATOR = + new ValueEvalToNumericXlator((short) + ( ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + )); + + public DivideEval(Ptg ptg) { + delegate = (DividePtg) ptg; + } + + protected ValueEvalToNumericXlator getXlator() { + return NUM_XLATOR; + } + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if(args.length != 2) { + return ErrorEval.VALUE_INVALID; + } + Eval retval = null; + double d0 = 0; + double d1 = 0; + ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d0 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.VALUE_INVALID; + } + + if (retval == null) { // no error yet + ve = singleOperandEvaluate(args[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d1 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + + if (retval == null) { + retval = (d1 == 0) + ? ErrorEval.DIV_ZERO + : (Double.isNaN(d0) || Double.isNaN(d1)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : new NumberEval(d0 / d1); + } + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/EqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/EqualEval.java new file mode 100644 index 0000000000..e7b169294e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/EqualEval.java @@ -0,0 +1,67 @@ +/* +* 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.EqualPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class EqualEval extends RelationalOperationEval { + + private EqualPtg delegate; + + public EqualEval(Ptg ptg) { + this.delegate = (EqualPtg) ptg; + } + + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + + RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); + retval = rvs.ee; + int result = 0; + if (retval == null) { + result = doComparison(rvs.bs); + if (result == 0) { + result = doComparison(rvs.ss); + } + if (result == 0) { + result = doComparison(rvs.ds); + } + + retval = (result == 0) ? BoolEval.TRUE : BoolEval.FALSE; + } + + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} 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 new file mode 100644 index 0000000000..e8e197d201 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/ErrorEval.java @@ -0,0 +1,113 @@ +/* +* 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.usermodel.HSSFErrorConstants; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class ErrorEval implements ValueEval { + + // convenient access to namespace + private static final HSSFErrorConstants 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; + + public static final ErrorEval FUNCTION_NOT_IMPLEMENTED = new ErrorEval(FUNCTION_NOT_IMPLEMENTED_CODE); + // 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 HSSFErrorConstants.ERROR_NULL: return NULL_INTERSECTION; + case HSSFErrorConstants.ERROR_DIV_0: return DIV_ZERO; + case HSSFErrorConstants.ERROR_VALUE: return VALUE_INVALID; + case HSSFErrorConstants.ERROR_REF: return REF_INVALID; + case HSSFErrorConstants.ERROR_NAME: return NAME_INVALID; + case HSSFErrorConstants.ERROR_NUM: return NUM_ERROR; + case HSSFErrorConstants.ERROR_NA: return NA; + // non-std errors (conditions modeled as errors by POI) + case CIRCULAR_REF_ERROR_CODE: return CIRCULAR_REF_ERROR; + case FUNCTION_NOT_IMPLEMENTED_CODE: return FUNCTION_NOT_IMPLEMENTED; + } + 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(HSSFErrorConstants.isValidCode(errorCode)) { + return HSSFErrorConstants.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/Eval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Eval.java new file mode 100644 index 0000000000..086b765a30 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Eval.java @@ -0,0 +1,29 @@ +/* +* 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 Eval { + +} 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 new file mode 100755 index 0000000000..7a23901b25 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/EvaluationException.java @@ -0,0 +1,134 @@ +/* ==================================================================== + 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/ExternalFunction.java b/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java new file mode 100755 index 0000000000..b1d81e6524 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java @@ -0,0 +1,81 @@ +/* ==================================================================== + 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.FreeRefFunction; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +/** + * + * Common entry point for all external functions (where + * AbstractFunctionPtg.field_2_fnc_index == 255) + * + * @author Josh Micich + */ +final class ExternalFunction implements FreeRefFunction { + + public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { + + int nIncomingArgs = args.length; + if(nIncomingArgs < 1) { + throw new RuntimeException("function name argument missing"); + } + + if (!(args[0] instanceof NameEval)) { + throw new RuntimeException("First argument should be a NameEval, but got (" + + args[0].getClass().getName() + ")"); + } + NameEval functionNameEval = (NameEval) args[0]; + + int nOutGoingArgs = nIncomingArgs -1; + Eval[] outGoingArgs = new Eval[nOutGoingArgs]; + System.arraycopy(args, 1, outGoingArgs, 0, nOutGoingArgs); + + FreeRefFunction targetFunc; + try { + targetFunc = findTargetFunction(workbook, functionNameEval); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + + return targetFunc.evaluate(outGoingArgs, srcCellRow, srcCellCol, workbook, sheet); + } + + private FreeRefFunction findTargetFunction(HSSFWorkbook workbook, NameEval functionNameEval) throws EvaluationException { + + int numberOfNames = workbook.getNumberOfNames(); + + int nameIndex = functionNameEval.getIndex(); + if(nameIndex < 0 || nameIndex >= numberOfNames) { + throw new RuntimeException("Bad name index (" + nameIndex + + "). Allowed range is (0.." + (numberOfNames-1) + ")"); + } + + String functionName = workbook.getNameName(nameIndex); + if(false) { + System.out.println("received call to external function index (" + functionName + ")"); + } + // TODO - detect if the NameRecord corresponds to a named range, function, or something undefined + // throw the right errors in these cases + + // TODO find the implementation for the external function e.g. "YEARFRAC" or "ISEVEN" + + throw new EvaluationException(ErrorEval.FUNCTION_NOT_IMPLEMENTED); + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java new file mode 100644 index 0000000000..375d6b35da --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java @@ -0,0 +1,60 @@ +/* +* 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.AbstractFunctionPtg; +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.record.formula.functions.Function; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class FuncVarEval extends FunctionEval { + + private AbstractFunctionPtg delegate; + + public FuncVarEval(Ptg funcPtg) { + delegate = (AbstractFunctionPtg) funcPtg; + } + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + Eval retval = null; + Function f = getFunction(); + if (f != null) + retval = f.evaluate(operands, srcRow, srcCol); + else + retval = ErrorEval.FUNCTION_NOT_IMPLEMENTED; + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } + + public short getFunctionIndex() { + return delegate.getFunctionIndex(); + } +} 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 new file mode 100644 index 0000000000..533c604a0c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/FunctionEval.java @@ -0,0 +1,435 @@ +/* +* 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 java.util.HashMap; +import java.util.Map; + +import org.apache.poi.hssf.record.formula.functions.*; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class FunctionEval implements OperationEval { + /** + * Some function IDs that require special treatment + */ + private static final class FunctionID { + /** 78 */ + public static final int OFFSET = 78; + /** 148 */ + public static final int INDIRECT = 148; + /** 255 */ + public static final int EXTERNAL_FUNC = 255; + } + // convenient access to namespace + private static final FunctionID ID = null; + + protected static Function[] functions = produceFunctions(); + + private static Map freeRefFunctionsByIdMap; + + static { + Map m = new HashMap(); + addMapping(m, ID.OFFSET, new Offset()); + addMapping(m, ID.INDIRECT, new Indirect()); + addMapping(m, ID.EXTERNAL_FUNC, new ExternalFunction()); + freeRefFunctionsByIdMap = m; + } + private static void addMapping(Map m, int offset, FreeRefFunction frf) { + m.put(createFRFKey(offset), frf); + } + private static Integer createFRFKey(int functionIndex) { + return new Integer(functionIndex); + } + + + public Function getFunction() { + short fidx = getFunctionIndex(); + return functions[fidx]; + } + public boolean isFreeRefFunction() { + return freeRefFunctionsByIdMap.containsKey(createFRFKey(getFunctionIndex())); + } + public FreeRefFunction getFreeRefFunction() { + return (FreeRefFunction) freeRefFunctionsByIdMap.get(createFRFKey(getFunctionIndex())); + } + + public abstract short getFunctionIndex(); + + private static Function[] produceFunctions() { + Function[] retval = new Function[368]; + retval[0] = new Count(); // COUNT + retval[1] = new If(); // IF + retval[2] = new IsNa(); // ISNA + retval[3] = new IsError(); // ISERROR + retval[4] = new Sum(); // SUM + retval[5] = new Average(); // AVERAGE + retval[6] = new Min(); // MIN + retval[7] = new Max(); // MAX + retval[8] = new Row(); // ROW + retval[9] = new Column(); // COLUMN + retval[10] = new Na(); // NA + retval[11] = new Npv(); // NPV + retval[12] = new Stdev(); // STDEV + retval[13] = new Dollar(); // DOLLAR + retval[14] = new Fixed(); // FIXED + retval[15] = new Sin(); // SIN + retval[16] = new Cos(); // COS + retval[17] = new Tan(); // TAN + retval[18] = new Atan(); // ATAN + retval[19] = new Pi(); // PI + retval[20] = new Sqrt(); // SQRT + retval[21] = new Exp(); // EXP + retval[22] = new Ln(); // LN + retval[23] = new Log10(); // LOG10 + retval[24] = new Abs(); // ABS + retval[25] = new Int(); // INT + retval[26] = new Sign(); // SIGN + retval[27] = new Round(); // ROUND + retval[28] = new Lookup(); // LOOKUP + retval[29] = new Index(); // INDEX + retval[30] = new Rept(); // REPT + retval[31] = new Mid(); // MID + retval[32] = new Len(); // LEN + retval[33] = new Value(); // VALUE + retval[34] = new True(); // TRUE + retval[35] = new False(); // FALSE + retval[36] = new And(); // AND + retval[37] = new Or(); // OR + retval[38] = new Not(); // NOT + retval[39] = new Mod(); // MOD + retval[40] = new Dcount(); // DCOUNT + retval[41] = new Dsum(); // DSUM + retval[42] = new Daverage(); // DAVERAGE + retval[43] = new Dmin(); // DMIN + retval[44] = new Dmax(); // DMAX + retval[45] = new Dstdev(); // DSTDEV + retval[46] = new Var(); // VAR + retval[47] = new Dvar(); // DVAR + retval[48] = new Text(); // TEXT + retval[49] = new Linest(); // LINEST + retval[50] = new Trend(); // TREND + retval[51] = new Logest(); // LOGEST + retval[52] = new Growth(); // GROWTH + retval[53] = new Goto(); // GOTO + retval[54] = new Halt(); // HALT + retval[56] = new Pv(); // PV + retval[57] = new Fv(); // FV + retval[58] = new Nper(); // NPER + retval[59] = new Pmt(); // PMT + retval[60] = new Rate(); // RATE + retval[61] = new Mirr(); // MIRR + retval[62] = new Irr(); // IRR + retval[63] = new Rand(); // RAND + retval[64] = new Match(); // MATCH + retval[65] = new Date(); // DATE + retval[66] = new Time(); // TIME + retval[67] = new Day(); // DAY + retval[68] = new Month(); // MONTH + retval[69] = new Year(); // YEAR + retval[70] = new Weekday(); // WEEKDAY + retval[71] = new Hour(); // HOUR + retval[72] = new Minute(); // MINUTE + retval[73] = new Second(); // SECOND + retval[74] = new Now(); // NOW + retval[75] = new Areas(); // AREAS + retval[76] = new Rows(); // ROWS + retval[77] = new Columns(); // COLUMNS + retval[ID.OFFSET] = null; // Offset.evaluate has a different signature + retval[79] = new Absref(); // ABSREF + retval[80] = new Relref(); // RELREF + retval[81] = new Argument(); // ARGUMENT + retval[82] = new Search(); // SEARCH + retval[83] = new Transpose(); // TRANSPOSE + retval[84] = new org.apache.poi.hssf.record.formula.functions.Error(); // ERROR + retval[85] = new Step(); // STEP + retval[86] = new Type(); // TYPE + retval[87] = new Echo(); // ECHO + retval[88] = new Setname(); // SETNAME + retval[89] = new Caller(); // CALLER + retval[90] = new Deref(); // DEREF + retval[91] = new NotImplementedFunction(); // WINDOWS + retval[92] = new Series(); // SERIES + retval[93] = new NotImplementedFunction(); // DOCUMENTS + retval[94] = new Activecell(); // ACTIVECELL + retval[95] = new NotImplementedFunction(); // SELECTION + retval[96] = new Result(); // RESULT + retval[97] = new Atan2(); // ATAN2 + retval[98] = new Asin(); // ASIN + retval[99] = new Acos(); // ACOS + retval[100] = new Choose(); // CHOOSE + retval[101] = new Hlookup(); // HLOOKUP + retval[102] = new Vlookup(); // VLOOKUP + retval[103] = new Links(); // LINKS + retval[104] = new Input(); // INPUT + retval[105] = new Isref(); // ISREF + retval[106] = new NotImplementedFunction(); // GETFORMULA + retval[107] = new NotImplementedFunction(); // GETNAME + retval[108] = new Setvalue(); // SETVALUE + retval[109] = new Log(); // LOG + retval[110] = new Exec(); // EXEC + retval[111] = new Char(); // CHAR + retval[112] = new Lower(); // LOWER + retval[113] = new Upper(); // UPPER + retval[114] = new Proper(); // PROPER + retval[115] = new Left(); // LEFT + retval[116] = new Right(); // RIGHT + retval[117] = new Exact(); // EXACT + retval[118] = new Trim(); // TRIM + retval[119] = new Replace(); // REPLACE + retval[120] = new Substitute(); // SUBSTITUTE + retval[121] = new Code(); // CODE + retval[122] = new Names(); // NAMES + retval[123] = new NotImplementedFunction(); // DIRECTORY + retval[124] = new Find(); // FIND + retval[125] = new Cell(); // CELL + retval[126] = new Iserr(); // ISERR + retval[127] = new Istext(); // ISTEXT + retval[128] = new Isnumber(); // ISNUMBER + retval[129] = new Isblank(); // ISBLANK + retval[130] = new T(); // T + retval[131] = new N(); // N + retval[132] = new NotImplementedFunction(); // FOPEN + retval[133] = new NotImplementedFunction(); // FCLOSE + retval[134] = new NotImplementedFunction(); // FSIZE + retval[135] = new NotImplementedFunction(); // FREADLN + retval[136] = new NotImplementedFunction(); // FREAD + retval[137] = new NotImplementedFunction(); // FWRITELN + retval[138] = new NotImplementedFunction(); // FWRITE + retval[139] = new Fpos(); // FPOS + retval[140] = new Datevalue(); // DATEVALUE + retval[141] = new Timevalue(); // TIMEVALUE + retval[142] = new Sln(); // SLN + retval[143] = new Syd(); // SYD + retval[144] = new Ddb(); // DDB + retval[145] = new NotImplementedFunction(); // GETDEF + retval[146] = new Reftext(); // REFTEXT + retval[147] = new Textref(); // TEXTREF + retval[ID.INDIRECT] = null; // Indirect.evaluate has different signature + retval[149] = new NotImplementedFunction(); // REGISTER + retval[150] = new Call(); // CALL + retval[151] = new NotImplementedFunction(); // ADDBAR + retval[152] = new NotImplementedFunction(); // ADDMENU + retval[153] = new NotImplementedFunction(); // ADDCOMMAND + retval[154] = new NotImplementedFunction(); // ENABLECOMMAND + retval[155] = new NotImplementedFunction(); // CHECKCOMMAND + retval[156] = new NotImplementedFunction(); // RENAMECOMMAND + retval[157] = new NotImplementedFunction(); // SHOWBAR + retval[158] = new NotImplementedFunction(); // DELETEMENU + retval[159] = new NotImplementedFunction(); // DELETECOMMAND + retval[160] = new NotImplementedFunction(); // GETCHARTITEM + retval[161] = new NotImplementedFunction(); // DIALOGBOX + retval[162] = new Clean(); // CLEAN + retval[163] = new Mdeterm(); // MDETERM + retval[164] = new Minverse(); // MINVERSE + retval[165] = new Mmult(); // MMULT + retval[166] = new Files(); // FILES + retval[167] = new Ipmt(); // IPMT + retval[168] = new Ppmt(); // PPMT + retval[169] = new Counta(); // COUNTA + retval[170] = new NotImplementedFunction(); // CANCELKEY + retval[175] = new Initiate(); // INITIATE + retval[176] = new Request(); // REQUEST + retval[177] = new NotImplementedFunction(); // POKE + retval[178] = new NotImplementedFunction(); // EXECUTE + retval[179] = new NotImplementedFunction(); // TERMINATE + retval[180] = new NotImplementedFunction(); // RESTART + retval[181] = new Help(); // HELP + retval[182] = new NotImplementedFunction(); // GETBAR + retval[183] = new Product(); // PRODUCT + retval[184] = new Fact(); // FACT + retval[185] = new NotImplementedFunction(); // GETCELL + retval[186] = new NotImplementedFunction(); // GETWORKSPACE + retval[187] = new NotImplementedFunction(); // GETWINDOW + retval[188] = new NotImplementedFunction(); // GETDOCUMENT + retval[189] = new Dproduct(); // DPRODUCT + retval[190] = new Isnontext(); // ISNONTEXT + retval[191] = new NotImplementedFunction(); // GETNOTE + retval[192] = new Note(); // NOTE + retval[193] = new Stdevp(); // STDEVP + retval[194] = new Varp(); // VARP + retval[195] = new Dstdevp(); // DSTDEVP + retval[196] = new Dvarp(); // DVARP + retval[197] = new Trunc(); // TRUNC + retval[198] = new Islogical(); // ISLOGICAL + retval[199] = new Dcounta(); // DCOUNTA + retval[200] = new NotImplementedFunction(); // DELETEBAR + retval[201] = new NotImplementedFunction(); // UNREGISTER + retval[204] = new Usdollar(); // USDOLLAR + retval[205] = new Findb(); // FINDB + retval[206] = new Searchb(); // SEARCHB + retval[207] = new Replaceb(); // REPLACEB + retval[208] = new Leftb(); // LEFTB + retval[209] = new Rightb(); // RIGHTB + retval[210] = new Midb(); // MIDB + retval[211] = new Lenb(); // LENB + retval[212] = new Roundup(); // ROUNDUP + retval[213] = new Rounddown(); // ROUNDDOWN + retval[214] = new Asc(); // ASC + retval[215] = new Dbcs(); // DBCS + retval[216] = new Rank(); // RANK + retval[219] = new Address(); // ADDRESS + retval[220] = new Days360(); // DAYS360 + retval[221] = new Today(); // TODAY + retval[222] = new Vdb(); // VDB + retval[227] = new Median(); // MEDIAN + retval[228] = new Sumproduct(); // SUMPRODUCT + retval[229] = new Sinh(); // SINH + retval[230] = new Cosh(); // COSH + retval[231] = new Tanh(); // TANH + retval[232] = new Asinh(); // ASINH + retval[233] = new Acosh(); // ACOSH + retval[234] = new Atanh(); // ATANH + retval[235] = new Dget(); // DGET + retval[236] = new NotImplementedFunction(); // CREATEOBJECT + retval[237] = new Volatile(); // VOLATILE + retval[238] = new Lasterror(); // LASTERROR + retval[239] = new NotImplementedFunction(); // CUSTOMUNDO + retval[240] = new Customrepeat(); // CUSTOMREPEAT + retval[241] = new Formulaconvert(); // FORMULACONVERT + retval[242] = new NotImplementedFunction(); // GETLINKINFO + retval[243] = new NotImplementedFunction(); // TEXTBOX + retval[244] = new Info(); // INFO + retval[245] = new Group(); // GROUP + retval[246] = new NotImplementedFunction(); // GETOBJECT + retval[247] = new Db(); // DB + retval[248] = new NotImplementedFunction(); // PAUSE + retval[250] = new NotImplementedFunction(); // RESUME + retval[252] = new Frequency(); // FREQUENCY + retval[253] = new NotImplementedFunction(); // ADDTOOLBAR + retval[254] = new NotImplementedFunction(); // DELETETOOLBAR + retval[ID.EXTERNAL_FUNC] = null; // ExternalFunction is a FreeREfFunction + retval[256] = new NotImplementedFunction(); // RESETTOOLBAR + retval[257] = new Evaluate(); // EVALUATE + retval[258] = new NotImplementedFunction(); // GETTOOLBAR + retval[259] = new NotImplementedFunction(); // GETTOOL + retval[260] = new NotImplementedFunction(); // SPELLINGCHECK + retval[261] = new Errortype(); // ERRORTYPE + retval[262] = new NotImplementedFunction(); // APPTITLE + retval[263] = new NotImplementedFunction(); // WINDOWTITLE + retval[264] = new NotImplementedFunction(); // SAVETOOLBAR + retval[265] = new NotImplementedFunction(); // ENABLETOOL + retval[266] = new NotImplementedFunction(); // PRESSTOOL + retval[267] = new NotImplementedFunction(); // REGISTERID + retval[268] = new NotImplementedFunction(); // GETWORKBOOK + retval[269] = new Avedev(); // AVEDEV + retval[270] = new Betadist(); // BETADIST + retval[271] = new Gammaln(); // GAMMALN + retval[272] = new Betainv(); // BETAINV + retval[273] = new Binomdist(); // BINOMDIST + retval[274] = new Chidist(); // CHIDIST + retval[275] = new Chiinv(); // CHIINV + retval[276] = new Combin(); // COMBIN + retval[277] = new Confidence(); // CONFIDENCE + retval[278] = new Critbinom(); // CRITBINOM + retval[279] = new Even(); // EVEN + retval[280] = new Expondist(); // EXPONDIST + retval[281] = new Fdist(); // FDIST + retval[282] = new Finv(); // FINV + retval[283] = new Fisher(); // FISHER + retval[284] = new Fisherinv(); // FISHERINV + retval[285] = new Floor(); // FLOOR + retval[286] = new Gammadist(); // GAMMADIST + retval[287] = new Gammainv(); // GAMMAINV + retval[288] = new Ceiling(); // CEILING + retval[289] = new Hypgeomdist(); // HYPGEOMDIST + retval[290] = new Lognormdist(); // LOGNORMDIST + retval[291] = new Loginv(); // LOGINV + retval[292] = new Negbinomdist(); // NEGBINOMDIST + retval[293] = new Normdist(); // NORMDIST + retval[294] = new Normsdist(); // NORMSDIST + retval[295] = new Norminv(); // NORMINV + retval[296] = new Normsinv(); // NORMSINV + retval[297] = new Standardize(); // STANDARDIZE + retval[298] = new Odd(); // ODD + retval[299] = new Permut(); // PERMUT + retval[300] = new Poisson(); // POISSON + retval[301] = new Tdist(); // TDIST + retval[302] = new Weibull(); // WEIBULL + retval[303] = new Sumxmy2(); // SUMXMY2 + retval[304] = new Sumx2my2(); // SUMX2MY2 + retval[305] = new Sumx2py2(); // SUMX2PY2 + retval[306] = new Chitest(); // CHITEST + retval[307] = new Correl(); // CORREL + retval[308] = new Covar(); // COVAR + retval[309] = new Forecast(); // FORECAST + retval[310] = new Ftest(); // FTEST + retval[311] = new Intercept(); // INTERCEPT + retval[312] = new Pearson(); // PEARSON + retval[313] = new Rsq(); // RSQ + retval[314] = new Steyx(); // STEYX + retval[315] = new Slope(); // SLOPE + retval[316] = new Ttest(); // TTEST + retval[317] = new Prob(); // PROB + retval[318] = new Devsq(); // DEVSQ + retval[319] = new Geomean(); // GEOMEAN + retval[320] = new Harmean(); // HARMEAN + retval[321] = new Sumsq(); // SUMSQ + retval[322] = new Kurt(); // KURT + retval[323] = new Skew(); // SKEW + retval[324] = new Ztest(); // ZTEST + retval[325] = new Large(); // LARGE + retval[326] = new Small(); // SMALL + retval[327] = new Quartile(); // QUARTILE + retval[328] = new Percentile(); // PERCENTILE + retval[329] = new Percentrank(); // PERCENTRANK + retval[330] = new Mode(); // MODE + retval[331] = new Trimmean(); // TRIMMEAN + retval[332] = new Tinv(); // TINV + retval[334] = new NotImplementedFunction(); // MOVIECOMMAND + retval[335] = new NotImplementedFunction(); // GETMOVIE + retval[336] = new Concatenate(); // CONCATENATE + retval[337] = new Power(); // POWER + retval[338] = new NotImplementedFunction(); // PIVOTADDDATA + retval[339] = new NotImplementedFunction(); // GETPIVOTTABLE + retval[340] = new NotImplementedFunction(); // GETPIVOTFIELD + retval[341] = new NotImplementedFunction(); // GETPIVOTITEM + retval[342] = new Radians(); // RADIANS + retval[343] = new Degrees(); // DEGREES + retval[344] = new Subtotal(); // SUBTOTAL + retval[345] = new Sumif(); // SUMIF + retval[346] = new Countif(); // COUNTIF + retval[347] = new Countblank(); // COUNTBLANK + retval[348] = new NotImplementedFunction(); // SCENARIOGET + retval[349] = new NotImplementedFunction(); // OPTIONSLISTSGET + retval[350] = new Ispmt(); // ISPMT + retval[351] = new Datedif(); // DATEDIF + retval[352] = new Datestring(); // DATESTRING + retval[353] = new Numberstring(); // NUMBERSTRING + retval[354] = new Roman(); // ROMAN + retval[355] = new NotImplementedFunction(); // OPENDIALOG + retval[356] = new NotImplementedFunction(); // SAVEDIALOG + retval[357] = new NotImplementedFunction(); // VIEWGET + retval[358] = new NotImplementedFunction(); // GETPIVOTDATA + retval[359] = new Hyperlink(); // HYPERLINK + retval[360] = new NotImplementedFunction(); // PHONETIC + retval[361] = new Averagea(); // AVERAGEA + retval[362] = new Maxa(); // MAXA + retval[363] = new Mina(); // MINA + retval[364] = new Stdevpa(); // STDEVPA + retval[365] = new Varpa(); // VARPA + retval[366] = new Stdeva(); // STDEVA + retval[367] = new Vara(); // VARA + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java new file mode 100644 index 0000000000..6a9a23217b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java @@ -0,0 +1,67 @@ +/* +* 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.GreaterEqualPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class GreaterEqualEval extends RelationalOperationEval { + + private GreaterEqualPtg delegate; + + public GreaterEqualEval(Ptg ptg) { + this.delegate = (GreaterEqualPtg) ptg; + } + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + + RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); + retval = rvs.ee; + int result = 0; + if (retval == null) { + result = doComparison(rvs.bs); + if (result == 0) { + result = doComparison(rvs.ss); + } + if (result == 0) { + result = doComparison(rvs.ds); + } + + retval = (result >= 0) ? BoolEval.TRUE : BoolEval.FALSE; + } + + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java new file mode 100644 index 0000000000..27da54a046 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java @@ -0,0 +1,67 @@ +/* +* 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.GreaterThanPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class GreaterThanEval extends RelationalOperationEval { + + private GreaterThanPtg delegate; + + public GreaterThanEval(Ptg ptg) { + this.delegate = (GreaterThanPtg) ptg; + } + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + + RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); + retval = rvs.ee; + int result = 0; + if (retval == null) { + result = doComparison(rvs.bs); + if (result == 0) { + result = doComparison(rvs.ss); + } + if (result == 0) { + result = doComparison(rvs.ds); + } + + retval = (result > 0) ? BoolEval.TRUE : BoolEval.FALSE;; + } + + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java new file mode 100644 index 0000000000..e45bf9e6bb --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java @@ -0,0 +1,67 @@ +/* +* 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.LessEqualPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class LessEqualEval extends RelationalOperationEval { + + private LessEqualPtg delegate; + + public LessEqualEval(Ptg ptg) { + this.delegate = (LessEqualPtg) ptg; + } + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + + RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); + retval = rvs.ee; + int result = 0; + if (retval == null) { + result = doComparison(rvs.bs); + if (result == 0) { + result = doComparison(rvs.ss); + } + if (result == 0) { + result = doComparison(rvs.ds); + } + + retval = (result <= 0) ? BoolEval.TRUE : BoolEval.FALSE;; + } + + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/LessThanEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/LessThanEval.java new file mode 100644 index 0000000000..1aac6f73bf --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/LessThanEval.java @@ -0,0 +1,68 @@ +/* +* 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.LessThanPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class LessThanEval extends RelationalOperationEval { + + private LessThanPtg delegate; + + public LessThanEval(Ptg ptg) { + this.delegate = (LessThanPtg) ptg; + } + + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + + RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); + retval = rvs.ee; + int result = 0; + if (retval == null) { + result = doComparison(rvs.bs); + if (result == 0) { + result = doComparison(rvs.ss); + } + if (result == 0) { + result = doComparison(rvs.ds); + } + + retval = (result < 0) ? BoolEval.TRUE : BoolEval.FALSE;; + } + + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java new file mode 100644 index 0000000000..22d87b7e4d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java @@ -0,0 +1,89 @@ +/* +* 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.MultiplyPtg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class MultiplyEval extends NumericOperationEval { + + private MultiplyPtg delegate; + + private static final ValueEvalToNumericXlator NUM_XLATOR = + new ValueEvalToNumericXlator((short) + ( ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + )); + + public MultiplyEval(Ptg ptg) { + delegate = (MultiplyPtg) ptg; + } + + protected ValueEvalToNumericXlator getXlator() { + return NUM_XLATOR; + } + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if(args.length != 2) { + return ErrorEval.VALUE_INVALID; + } + + double d0 = 0; + double d1 = 0; + ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d0 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + return ErrorEval.VALUE_INVALID; + } + + ve = singleOperandEvaluate(args[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d1 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + return ErrorEval.VALUE_INVALID; + } + + if (Double.isNaN(d0) || Double.isNaN(d1)) { + return ErrorEval.NUM_ERROR; + } + return new NumberEval(d0 * d1); + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} 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 new file mode 100755 index 0000000000..682394b3c2 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/NameEval.java @@ -0,0 +1,48 @@ +/* ==================================================================== + 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 Eval { + + private final int _index; + + /** + * @param index zero based index to a defined name record + */ + public NameEval(int index) { + _index = index; + } + + /** + * @return zero based index to a defined name record + */ + public int getIndex() { + return _index; + } + + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append(getClass().getName()).append(" ["); + sb.append(_index); + sb.append("]"); + return sb.toString(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java new file mode 100644 index 0000000000..c5388f520f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java @@ -0,0 +1,68 @@ +/* +* 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.NotEqualPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class NotEqualEval extends RelationalOperationEval { + + private NotEqualPtg delegate; + + public NotEqualEval(Ptg ptg) { + this.delegate = (NotEqualPtg) ptg; + } + + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + + RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); + retval = rvs.ee; + int result = 0; + if (retval == null) { + result = doComparison(rvs.bs); + if (result == 0) { + result = doComparison(rvs.ss); + } + if (result == 0) { + result = doComparison(rvs.ds); + } + + retval = (result != 0) ? BoolEval.TRUE : BoolEval.FALSE; + } + + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } + +} 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 new file mode 100644 index 0000000000..44a017f631 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/NumberEval.java @@ -0,0 +1,73 @@ +/* +* 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; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class NumberEval implements NumericValueEval, StringValueEval { + + public static final NumberEval ZERO = new NumberEval(0); + + private double value; + private String stringValue; + + public NumberEval(Ptg ptg) { + if (ptg instanceof IntPtg) { + this.value = ((IntPtg) ptg).getValue(); + } + else if (ptg instanceof NumberPtg) { + this.value = ((NumberPtg) ptg).getValue(); + } + } + + public NumberEval(double value) { + this.value = value; + } + + public double getNumberValue() { + return value; + } + + public String getStringValue() { // TODO: limit to 15 decimal places + if (stringValue == null) + makeString(); + return stringValue; + } + + protected void makeString() { + if (!Double.isNaN(value)) { + long lvalue = Math.round(value); + if (lvalue == value) { + stringValue = String.valueOf(lvalue); + } + else { + stringValue = String.valueOf(value); + } + } + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java new file mode 100644 index 0000000000..6bc1c95dc1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java @@ -0,0 +1,66 @@ +/* +* 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 14, 2005 + * + */ +package org.apache.poi.hssf.record.formula.eval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class NumericOperationEval implements OperationEval { + + protected abstract ValueEvalToNumericXlator getXlator(); + + protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { + ValueEval retval; + if (eval instanceof AreaEval) { + AreaEval ae = (AreaEval) eval; + if (ae.contains(srcRow, srcCol)) { // circular ref! + retval = ErrorEval.CIRCULAR_REF_ERROR; + } + else if (ae.isRow()) { + if (ae.containsColumn(srcCol)) { + ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); + ve = getXlator().attemptXlateToNumeric(ve); + retval = getXlator().attemptXlateToNumeric(ve); + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else if (ae.isColumn()) { + if (ae.containsRow(srcRow)) { + ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); + retval = getXlator().attemptXlateToNumeric(ve); + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else { + retval = getXlator().attemptXlateToNumeric((ValueEval) eval); + } + return retval; + } +} 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 new file mode 100644 index 0000000000..d5b92b8080 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java @@ -0,0 +1,30 @@ +/* +* 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 new file mode 100755 index 0000000000..be1cda5f8e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java @@ -0,0 +1,277 @@ +/* ==================================================================== + 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; + +/** + * Provides functionality for evaluating arguments to functions and operators. + * + * @author Josh Micich + */ +public final class OperandResolver { + + 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(Eval arg, int srcCellRow, short srcCellCol) + throws EvaluationException { + Eval 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); + } + if (result instanceof ValueEval) { + return (ValueEval) result; + } + throw new RuntimeException("Unexpected eval type (" + result.getClass().getName() + ")"); + } + + /** + * 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. + * + * + * + * + * + * + * + *
      A  B  C  D 
    1152025 
    2   200
    3   300
    3   400
    + * + * 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 
    1152025 
    212151220#VALUE!200
    313151320#VALUE!300
    4#VALUE!#VALUE!#VALUE!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 ErrorEval.CIRCULAR_REF_ERROR upon entry to this method. It + * is assumed logic exists elsewhere to produce this behaviour. + * + * @return whatever the selected cell's evaluated value is. Never 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, short srcCellCol) throws EvaluationException { + ValueEval result = chooseSingleElementFromAreaInternal(ae, srcCellRow, srcCellCol); + if(result == null) { + // This seems to be required because AreaEval.values() array may contain nulls. + // perhaps that should not be allowed. + result = BlankEval.INSTANCE; + } + if (result instanceof ErrorEval) { + throw new EvaluationException((ErrorEval) result); + + } + return result; + } + + /** + * @return possibly ErrorEval, and null + */ + private static ValueEval chooseSingleElementFromAreaInternal(AreaEval ae, + int srcCellRow, short 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 HSSFFormulaEvaluator). + */ + } + + if (ae.isColumn()) { + if(ae.isRow()) { + return ae.getValues()[0]; + } + if(!ae.containsRow(srcCellRow)) { + throw EvaluationException.invalidValue(); + } + return ae.getValueAt(srcCellRow, ae.getFirstColumn()); + } + if(!ae.isRow()) { + // multi-column, multi-row area + if(ae.containsRow(srcCellRow) && ae.containsColumn(srcCellCol)) { + return ae.getValueAt(ae.getFirstRow(), ae.getFirstColumn()); + } + throw EvaluationException.invalidValue(); + } + if(!ae.containsColumn(srcCellCol)) { + throw EvaluationException.invalidValue(); + } + return ae.getValueAt(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() ).

    + * + * 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 { + 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 not supported and must be handled by the caller. + * @param ev must be a NumberEval, StringEval or BoolEval + * @return actual, parsed or interpreted double value (respectively). + * @throws EvaluationException(#VALUE!) only if a StringEval is supplied and cannot be parsed + * as a double (See parseDouble() for allowable formats). + * @throws RuntimeException if the supplied parameter is not NumberEval, + * StringEval or BoolEval + */ + public static double coerceValueToDouble(ValueEval ev) throws EvaluationException { + + 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 currency prefixes, commas, leading and trailing spaces.

    + * + * Some examples:
    + * " 123 " -> 123.0
    + * ".123" -> 0.123
    + * These not supported yet:
    + * " $ 1,000.00 " -> 1000.0
    + * "$1.25E4" -> 12500.0
    + * "5**2" -> 500
    + * "250%" -> 2.5
    + * + * @param text + * @return null if the specified text cannot be parsed as a number + */ + public static Double parseDouble(String pText) { + String text = pText.trim(); + if(text.length() < 1) { + return null; + } + boolean isPositive = true; + if(text.charAt(0) == '-') { + isPositive = false; + text= text.substring(1).trim(); + } + + if(!Character.isDigit(text.charAt(0))) { + // avoid using NumberFormatException to tell when string is not a number + return null; + } + // TODO - support notation like '1E3' (==1000) + + double val; + try { + val = Double.parseDouble(text); + } catch (NumberFormatException e) { + return null; + } + return new Double(isPositive ? +val : -val); + } + + /** + * @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 instanceof NumberEval) { + NumberEval neval = (NumberEval) ve; + return neval.getStringValue(); + } + + if (ve instanceof BlankEval) { + return ""; + } + throw new IllegalArgumentException("Unexpected eval class (" + ve.getClass().getName() + ")"); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/OperationEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/OperationEval.java new file mode 100644 index 0000000000..aefd5aefad --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/OperationEval.java @@ -0,0 +1,53 @@ +/* +* 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 OperationEval extends Eval { + + /* + * Read this, this will make your work easier when coding + * an "evaluate()" + * + * Things to note when implementing evaluate(): + * 1. Check the length of operands + * (use "switch(operands[x])" if possible) + * + * 2. The possible Evals that you can get as args to evaluate are one of: + * NumericValueEval, StringValueEval, RefEval, AreaEval + * 3. If it is RefEval, the innerValueEval could be one of: + * NumericValueEval, StringValueEval, BlankEval + * 4. If it is AreaEval, each of the values could be one of: + * NumericValueEval, StringValueEval, BlankEval, RefEval + * + * 5. For numeric functions/operations, keep the result in double + * till the end and before returning a new NumberEval, check to see + * if the double is a NaN - if NaN, return ErrorEval.ERROR_503 + */ + public abstract Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol); + + public abstract int getNumberOfOperands(); + + public abstract int getType(); +} 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 new file mode 100755 index 0000000000..c698a4e502 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/PercentEval.java @@ -0,0 +1,71 @@ +/* ==================================================================== + 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.PercentPtg; +import org.apache.poi.hssf.record.formula.Ptg; + +/** + * Implementation of Excel formula token '%'.

    + * @author Josh Micich + */ +public final class PercentEval extends NumericOperationEval { + + private PercentPtg _delegate; + + private static final ValueEvalToNumericXlator NUM_XLATOR = new ValueEvalToNumericXlator( + (short) (ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED | ValueEvalToNumericXlator.REF_STRING_IS_PARSED)); + + public PercentEval(Ptg ptg) { + _delegate = (PercentPtg) ptg; + } + + protected ValueEvalToNumericXlator getXlator() { + return NUM_XLATOR; + } + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if (args.length != 1) { + return ErrorEval.VALUE_INVALID; + } + + ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + double d0 = ((NumericValueEval) ve).getNumberValue(); + return new NumberEval(d0 / 100); + } + + if (ve instanceof BlankEval) { + return NumberEval.ZERO; + } + if (ve instanceof ErrorEval) { + return ve; + } + return ErrorEval.VALUE_INVALID; + } + + public int getNumberOfOperands() { + return _delegate.getNumberOfOperands(); + } + + public int getType() { + return _delegate.getType(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/PowerEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/PowerEval.java new file mode 100644 index 0000000000..651c5d2aa2 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/PowerEval.java @@ -0,0 +1,90 @@ +/* +* 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.PowerPtg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class PowerEval extends NumericOperationEval { + + private PowerPtg delegate; + + private static final ValueEvalToNumericXlator NUM_XLATOR = + new ValueEvalToNumericXlator((short) + ( ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + )); + + public PowerEval(Ptg ptg) { + delegate = (PowerPtg) ptg; + } + + protected ValueEvalToNumericXlator getXlator() { + return NUM_XLATOR; + } + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if(args.length != 2) { + return ErrorEval.VALUE_INVALID; + } + double d0 = 0; + double d1 = 0; + + ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d0 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + return ErrorEval.VALUE_INVALID; + } + + ve = singleOperandEvaluate(args[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d1 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + return ErrorEval.VALUE_INVALID; + } + + double p = Math.pow(d0, d1); + if (Double.isNaN(p)) { + return ErrorEval.VALUE_INVALID; + } + return new NumberEval(p); + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java new file mode 100644 index 0000000000..898d7a8618 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java @@ -0,0 +1,50 @@ +/* +* 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.ReferencePtg; + +/** + * @author adeshmukh + * + */ +public final class Ref2DEval implements RefEval { + + private final ValueEval value; + private final ReferencePtg delegate; + + public Ref2DEval(ReferencePtg ptg, ValueEval ve) { + if(ve == null) { + throw new IllegalArgumentException("ve must not be null"); + } + if(false && ptg == null) { // TODO - fix dodgy code in MultiOperandNumericFunction + throw new IllegalArgumentException("ptg must not be null"); + } + value = ve; + delegate = ptg; + } + public ValueEval getInnerValueEval() { + return value; + } + public int getRow() { + return delegate.getRow(); + } + public int getColumn() { + return delegate.getColumn(); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java new file mode 100644 index 0000000000..622d686329 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java @@ -0,0 +1,53 @@ +/* +* 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.Ref3DPtg; + +/** + * @author Amol S. Deshmukh + * + */ +public final class Ref3DEval implements RefEval { + + private final ValueEval value; + private final Ref3DPtg delegate; + + public Ref3DEval(Ref3DPtg ptg, ValueEval ve) { + if(ve == null) { + throw new IllegalArgumentException("ve must not be null"); + } + if(ptg == null) { + throw new IllegalArgumentException("ptg must not be null"); + } + value = ve; + delegate = ptg; + } + public ValueEval getInnerValueEval() { + return value; + } + public int getRow() { + return delegate.getRow(); + } + public int getColumn() { + return delegate.getColumn(); + } + public int getExternSheetIndex() { + return delegate.getExternSheetIndex(); + } +} 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 new file mode 100644 index 0000000000..e462586d72 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/RefEval.java @@ -0,0 +1,51 @@ +/* +* 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 HSSFCell 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 { + + /** + * The (possibly evaluated) ValueEval contained + * in this RefEval. eg. if cell A1 contains "test" + * then in a formula referring to cell A1 + * the RefEval representing + * A1 will return as the getInnerValueEval() the + * object of concrete type StringEval + */ + public ValueEval getInnerValueEval(); + + /** + * returns the zero based column index. + */ + public int getColumn(); + + /** + * returns the zero based row index. + */ + public int getRow(); +} 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 new file mode 100644 index 0000000000..9b1a2ece4f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java @@ -0,0 +1,216 @@ +/* +* 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 10, 2005 + * + */ +package org.apache.poi.hssf.record.formula.eval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class RelationalOperationEval implements OperationEval { + + protected class RelationalValues { + public Double[] ds = new Double[2]; + public Boolean[] bs = new Boolean[2]; + public String[] ss = new String[3]; + public ErrorEval ee = null; + } + + + /* + * 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 > any number. ALWAYS + * Bool > any string. ALWAYS + * Bool.TRUE > Bool.FALSE + * + * String > any number. ALWAYS + * String > Blank. ALWAYS + * String are sorted dictionary wise + * + * Blank == 0 (numeric) + */ + public RelationalValues doEvaluate(Eval[] operands, int srcRow, short srcCol) { + RelationalValues retval = new RelationalValues(); + + switch (operands.length) { + default: + retval.ee = ErrorEval.VALUE_INVALID; + break; + case 2: + internalDoEvaluate(operands, srcRow, srcCol, retval, 0); + internalDoEvaluate(operands, srcRow, srcCol, retval, 1); + } // end switch + return retval; + } + + /** + * convenience method to avoid code duplication for multiple operands + * @param operands + * @param srcRow + * @param srcCol + * @param retval + * @param index + */ + private void internalDoEvaluate(Eval[] operands, int srcRow, short srcCol, RelationalValues retval, int index) { + if (operands[index] instanceof BoolEval) { + BoolEval be = (BoolEval) operands[index]; + retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); + } + else if (operands[index] instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) operands[index]; + retval.ds[index] = new Double(ne.getNumberValue()); + } + else if (operands[index] instanceof StringValueEval) { + StringValueEval se = (StringValueEval) operands[index]; + retval.ss[index] = se.getStringValue(); + } + else if (operands[index] instanceof RefEval) { + RefEval re = (RefEval) operands[index]; + ValueEval ve = re.getInnerValueEval(); + if (ve instanceof BoolEval) { + BoolEval be = (BoolEval) ve; + retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); + } + else if (ve instanceof BlankEval) { + retval.ds[index] = new Double(0); + } + else if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + retval.ds[index] = new Double(ne.getNumberValue()); + } + else if (ve instanceof StringValueEval) { + StringValueEval se = (StringValueEval) ve; + retval.ss[index] = se.getStringValue(); + } + } + else if (operands[index] instanceof AreaEval) { + AreaEval ae = (AreaEval) operands[index]; + if (ae.isRow()) { + if (ae.containsColumn(srcCol)) { + ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); + if (ve instanceof BoolEval) { + BoolEval be = (BoolEval) ve; + retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); + } + else if (ve instanceof BlankEval) { + retval.ds[index] = new Double(0); + } + else if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + retval.ds[index] = new Double(ne.getNumberValue()); + } + else if (ve instanceof StringValueEval) { + StringValueEval se = (StringValueEval) ve; + retval.ss[index] = se.getStringValue(); + } + else { + retval.ee = ErrorEval.VALUE_INVALID; + } + } + else { + retval.ee = ErrorEval.VALUE_INVALID; + } + } + else if (ae.isColumn()) { + if (ae.containsRow(srcRow)) { + ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); + if (ve instanceof BoolEval) { + BoolEval be = (BoolEval) ve; + retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); + } + else if (ve instanceof BlankEval) { + retval.ds[index] = new Double(0); + } + else if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + retval.ds[index] = new Double(ne.getNumberValue()); + } + else if (ve instanceof StringValueEval) { + StringValueEval se = (StringValueEval) ve; + retval.ss[index] = se.getStringValue(); + } + else { + retval.ee = ErrorEval.VALUE_INVALID; + } + } + else { + retval.ee = ErrorEval.VALUE_INVALID; + } + } + else { + retval.ee = ErrorEval.VALUE_INVALID; + } + } + } + + // if both null return 0, else non null wins, else TRUE wins + protected int doComparison(Boolean[] bs) { + int retval = 0; + if (bs[0] != null || bs[1] != null) { + retval = bs[0] != null + ? bs[1] != null + ? bs[0].booleanValue() + ? bs[1].booleanValue() + ? 0 + : 1 + : bs[1].booleanValue() + ? -1 + : 0 + : 1 + : bs[1] != null + ? -1 + : 0; + } + return retval; + } + + // if both null return 0, else non null wins, else string compare + protected int doComparison(String[] ss) { + int retval = 0; + if (ss[0] != null || ss[1] != null) { + retval = ss[0] != null + ? ss[1] != null + ? ss[0].compareTo(ss[1]) + : 1 + : ss[1] != null + ? -1 + : 0; + } + return retval; + } + + // if both null return 0, else non null wins, else doublevalue compare + protected int doComparison(Double[] ds) { + int retval = 0; + if (ds[0] != null || ds[1] != null) { + retval = ds[0] != null + ? ds[1] != null + ? ds[0].compareTo(ds[1]) + : 1 + : ds[1] != null + ? -1 + : 0; + } + return retval; + } +} 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 new file mode 100644 index 0000000000..27a9c6a627 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/StringEval.java @@ -0,0 +1,54 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.poi.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"); + } + this.value = value; + } + + public String getStringValue() { + return value; + } + public String toString() { + StringBuffer sb = new StringBuffer(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/StringOperationEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java new file mode 100644 index 0000000000..e2a3c72a4c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java @@ -0,0 +1,96 @@ +/* +* 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 14, 2005 + * + */ +package org.apache.poi.hssf.record.formula.eval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class StringOperationEval implements OperationEval { + + + + /** + * Returns an instanceof StringValueEval or ErrorEval or BlankEval + * + * @param eval + * @param srcRow + * @param srcCol + */ + protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { + ValueEval retval; + if (eval instanceof AreaEval) { + AreaEval ae = (AreaEval) eval; + if (ae.contains(srcRow, srcCol)) { // circular ref! + retval = ErrorEval.CIRCULAR_REF_ERROR; + } + else if (ae.isRow()) { + if (ae.containsColumn(srcCol)) { + ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); + retval = internalResolveEval(eval); + } + else { + retval = ErrorEval.NAME_INVALID; + } + } + else if (ae.isColumn()) { + if (ae.containsRow(srcRow)) { + ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); + retval = internalResolveEval(eval); + } + else { + retval = ErrorEval.NAME_INVALID; + } + } + else { + retval = ErrorEval.NAME_INVALID; + } + } + else { + retval = internalResolveEval(eval); + } + return retval; + } + + private ValueEval internalResolveEval(Eval eval) { + ValueEval retval; + if (eval instanceof StringValueEval) { + retval = (StringValueEval) eval; + } + else if (eval instanceof RefEval) { + RefEval re = (RefEval) eval; + ValueEval tve = re.getInnerValueEval(); + if (tve instanceof StringValueEval || tve instanceof BlankEval) { + retval = tve; + } + else { + retval = ErrorEval.NAME_INVALID; + } + } + else if (eval instanceof BlankEval) { + retval = (BlankEval) eval; + } + else { + retval = ErrorEval.NAME_INVALID; + } + return retval; + } +} 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 new file mode 100644 index 0000000000..46c12236b9 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/StringValueEval.java @@ -0,0 +1,30 @@ +/* +* 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/SubtractEval.java b/src/java/org/apache/poi/hssf/record/formula/eval/SubtractEval.java new file mode 100644 index 0000000000..85a3845299 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/SubtractEval.java @@ -0,0 +1,93 @@ +/* +* 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.SubtractPtg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class SubtractEval extends NumericOperationEval { + + private SubtractPtg delegate; + + private static final ValueEvalToNumericXlator NUM_XLATOR = + new ValueEvalToNumericXlator((short) + ( ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + )); + + public SubtractEval(Ptg ptg) { + delegate = (SubtractPtg) ptg; + } + + protected ValueEvalToNumericXlator getXlator() { + return NUM_XLATOR; + } + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if(args.length != 2) { + return ErrorEval.VALUE_INVALID; + } + Eval retval = null; + double d0 = 0; + double d1 = 0; + ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d0 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.VALUE_INVALID; + } + + if (retval == null) { // no error yet + ve = singleOperandEvaluate(args[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d1 = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + + if (retval == null) { + retval = (Double.isNaN(d0) || Double.isNaN(d1)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : new NumberEval(d0 - d1); + } + return retval; + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} 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 new file mode 100644 index 0000000000..ef6f533ea5 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java @@ -0,0 +1,75 @@ +/* +* 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.UnaryMinusPtg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class UnaryMinusEval extends NumericOperationEval { + + private UnaryMinusPtg delegate; + private static final ValueEvalToNumericXlator NUM_XLATOR = + new ValueEvalToNumericXlator((short) + ( ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + )); + + + public UnaryMinusEval(Ptg ptg) { + this.delegate = (UnaryMinusPtg) ptg; + } + + protected ValueEvalToNumericXlator getXlator() { + return NUM_XLATOR; + } + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + if(args.length != 1) { + return ErrorEval.VALUE_INVALID; + } + double d = 0; + + ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + d = ((NumericValueEval) ve).getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else if (ve instanceof ErrorEval) { + return ve; + } + + return new NumberEval(-d); + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } + +} 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 new file mode 100644 index 0000000000..edcc7bee79 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java @@ -0,0 +1,68 @@ +/* +* 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.UnaryPlusPtg; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class UnaryPlusEval implements OperationEval { + + private UnaryPlusPtg delegate; + + /** + * called by reflection + */ + public UnaryPlusEval(Ptg ptg) { + this.delegate = (UnaryPlusPtg) ptg; + } + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + if(args.length != 1) { + return ErrorEval.VALUE_INVALID; + } + double d; + try { + ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + if(ve instanceof BlankEval) { + return NumberEval.ZERO; + } + if(ve instanceof StringEval) { + // Note - asymmetric with UnaryMinus + // -"hello" evaluates to #VALUE! + // but +"hello" evaluates to "hello" + return ve; + } + d = OperandResolver.coerceValueToDouble(ve); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + return new NumberEval(+d); + } + + public int getNumberOfOperands() { + return delegate.getNumberOfOperands(); + } + + public int getType() { + return delegate.getType(); + } +} 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 new file mode 100644 index 0000000000..4581fa4d6e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/ValueEval.java @@ -0,0 +1,29 @@ +/* +* 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 ValueEval extends Eval { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java b/src/java/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java new file mode 100644 index 0000000000..1abcf34d2b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java @@ -0,0 +1,188 @@ +/* +* 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 14, 2005 + * + */ +package org.apache.poi.hssf.record.formula.eval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class ValueEvalToNumericXlator { + + public static final int STRING_IS_PARSED = 0x0001; + public static final int BOOL_IS_PARSED = 0x0002; + public static final int BLANK_IS_PARSED = 0x0004; // => blanks are not ignored, converted to 0 + + public static final int REF_STRING_IS_PARSED = 0x0008; + public static final int REF_BOOL_IS_PARSED = 0x0010; + public static final int REF_BLANK_IS_PARSED = 0x0020; + + public static final int STRING_IS_INVALID_VALUE = 0x0800; + + private final int flags; + + + public ValueEvalToNumericXlator(int flags) { + + if (false) { // uncomment to see who is using this class + System.err.println(new Throwable().getStackTrace()[1].getClassName() + "\t0x" + + Integer.toHexString(flags).toUpperCase()); + } + this.flags = flags; + } + + /** + * returned value can be either A NumericValueEval, BlankEval or ErrorEval. + * The params can be either NumberEval, BoolEval, StringEval, or + * RefEval + * @param eval + */ + public ValueEval attemptXlateToNumeric(ValueEval eval) { + ValueEval retval = null; + + if (eval == null) { + retval = BlankEval.INSTANCE; + } + + // most common case - least worries :) + else if (eval instanceof NumberEval) { + retval = eval; + } + + // booleval + else if (eval instanceof BoolEval) { + retval = ((flags & BOOL_IS_PARSED) > 0) + ? (NumericValueEval) eval + : xlateBlankEval(BLANK_IS_PARSED); + } + + // stringeval + else if (eval instanceof StringEval) { + retval = xlateStringEval((StringEval) eval); // TODO: recursive call needed + } + + // refeval + else if (eval instanceof RefEval) { + retval = xlateRefEval((RefEval) eval); + } + + // erroreval + else if (eval instanceof ErrorEval) { + retval = eval; + } + + else if (eval instanceof BlankEval) { + retval = xlateBlankEval(BLANK_IS_PARSED); + } + + // probably AreaEval? then not acceptable. + else { + throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass()); + } + + return retval; + } + + /** + * no args are required since BlankEval has only one + * instance. If flag is set, a zero + * valued numbereval is returned, else BlankEval.INSTANCE + * is returned. + */ + private ValueEval xlateBlankEval(int flag) { + return ((flags & flag) > 0) + ? (ValueEval) NumberEval.ZERO + : BlankEval.INSTANCE; + } + + /** + * uses the relevant flags to decode the supplied RefVal + * @param eval + */ + private ValueEval xlateRefEval(RefEval reval) { + ValueEval eval = reval.getInnerValueEval(); + + // most common case - least worries :) + if (eval instanceof NumberEval) { + return eval; + } + + if (eval instanceof BoolEval) { + return ((flags & REF_BOOL_IS_PARSED) > 0) + ? (ValueEval) eval + : BlankEval.INSTANCE; + } + + if (eval instanceof StringEval) { + return xlateRefStringEval((StringEval) eval); + } + + if (eval instanceof ErrorEval) { + return eval; + } + + if (eval instanceof BlankEval) { + return xlateBlankEval(REF_BLANK_IS_PARSED); + } + + throw new RuntimeException("Invalid ValueEval type passed for conversion: (" + + eval.getClass().getName() + ")"); + } + + /** + * uses the relevant flags to decode the StringEval + * @param eval + */ + private ValueEval xlateStringEval(StringEval eval) { + + if ((flags & STRING_IS_PARSED) > 0) { + String s = eval.getStringValue(); + Double d = OperandResolver.parseDouble(s); + if(d == null) { + return ErrorEval.VALUE_INVALID; + } + return new NumberEval(d.doubleValue()); + } + // strings are errors? + if ((flags & STRING_IS_INVALID_VALUE) > 0) { + return ErrorEval.VALUE_INVALID; + } + + // ignore strings + return xlateBlankEval(BLANK_IS_PARSED); + } + + /** + * uses the relevant flags to decode the StringEval + * @param eval + */ + private ValueEval xlateRefStringEval(StringEval sve) { + if ((flags & REF_STRING_IS_PARSED) > 0) { + String s = sve.getStringValue(); + Double d = OperandResolver.parseDouble(s); + if(d == null) { + return ErrorEval.VALUE_INVALID; + } + return new NumberEval(d.doubleValue()); + } + // strings are blanks + return BlankEval.INSTANCE; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Abs.java b/src/java/org/apache/poi/hssf/record/formula/functions/Abs.java new file mode 100644 index 0000000000..1bebb358bb --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Abs.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Abs extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.abs(d); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Absref.java b/src/java/org/apache/poi/hssf/record/formula/functions/Absref.java new file mode 100644 index 0000000000..3a6e94a66e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Absref.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Absref extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Acos.java b/src/java/org/apache/poi/hssf/record/formula/functions/Acos.java new file mode 100644 index 0000000000..bc5b5720ee --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Acos.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Acos extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.acos(d); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java new file mode 100644 index 0000000000..794516e57f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Acosh.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * Support for hyperbolic trig functions was added as a part of + * Java distribution only in JDK1.5. This class uses custom + * naive implementation based on formulas at: + * http://www.math2.org/math/trig/hyperbolics.htm + * These formulas seem to agree with excel's implementation. + * + */ +public class Acosh extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + } + + if (retval == null) { + d = MathX.acosh(d); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Activecell.java b/src/java/org/apache/poi/hssf/record/formula/functions/Activecell.java new file mode 100644 index 0000000000..17b04137af --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Activecell.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Activecell extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Address.java b/src/java/org/apache/poi/hssf/record/formula/functions/Address.java new file mode 100644 index 0000000000..9b408e0d34 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Address.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Address extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/And.java b/src/java/org/apache/poi/hssf/record/formula/functions/And.java new file mode 100644 index 0000000000..455772f737 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/And.java @@ -0,0 +1,85 @@ +/* +* 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 9, 2005 + * + */ +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.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class And extends BooleanFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + boolean b = true; + boolean atleastOneNonBlank = false; + + /* + * Note: do not abort the loop if b is false, since we could be + * dealing with errorevals later. + */ + outer: + for (int i=0, iSize=operands.length; i + *

  • Blanks are not either true or false + *
  • Strings are not either true or false (even strings "true" + * or "TRUE" or "0" etc.) + *
  • Numbers: 0 is false. Any other number is TRUE. + *
  • References are evaluated and above rules apply. + *
  • Areas: Individual cells in area are evaluated and checked to + * see if they are blanks, strings etc. + * + */ +public abstract class BooleanFunction implements Function { + + protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol, boolean stringsAreBlanks) { + ValueEval retval; + + if (eval instanceof RefEval) { + RefEval re = (RefEval) eval; + ValueEval ve = re.getInnerValueEval(); + retval = internalResolve(ve, true); + } + else { + retval = internalResolve(eval, stringsAreBlanks); + } + + return retval; + } + + private ValueEval internalResolve(Eval ve, boolean stringsAreBlanks) { + ValueEval retval = null; + + // blankeval is returned as is + if (ve instanceof BlankEval) { + retval = BlankEval.INSTANCE; + } + + // stringeval + else if (ve instanceof StringEval) { + retval = stringsAreBlanks ? (ValueEval) BlankEval.INSTANCE : (StringEval) ve; + } + + // bools are bools :) + else if (ve instanceof BoolEval) { + retval = (BoolEval) ve; + } + + // convert numbers to bool + else if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + double d = ne.getNumberValue(); + retval = Double.isNaN(d) + ? (ValueEval) ErrorEval.VALUE_INVALID + : (d != 0) + ? BoolEval.TRUE + : BoolEval.FALSE; + } + + // since refevals + else { + retval = ErrorEval.VALUE_INVALID; + } + + return retval; + + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Call.java b/src/java/org/apache/poi/hssf/record/formula/functions/Call.java new file mode 100644 index 0000000000..a1cb4ca376 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Call.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Call extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Caller.java b/src/java/org/apache/poi/hssf/record/formula/functions/Caller.java new file mode 100644 index 0000000000..206d08a703 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Caller.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Caller extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ceiling.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ceiling.java new file mode 100644 index 0000000000..a158b856bc --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ceiling.java @@ -0,0 +1,82 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Ceiling extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d0 = 0; + double d1 = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d0 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + if (retval == null) { + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d1 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + double d = MathX.ceiling(d0, d1); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Cell.java b/src/java/org/apache/poi/hssf/record/formula/functions/Cell.java new file mode 100644 index 0000000000..ffbd322395 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Cell.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Cell extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Char.java b/src/java/org/apache/poi/hssf/record/formula/functions/Char.java new file mode 100644 index 0000000000..2c4271dc70 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Char.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Char extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Chidist.java b/src/java/org/apache/poi/hssf/record/formula/functions/Chidist.java new file mode 100644 index 0000000000..b431fe361a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Chidist.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Chidist extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Chiinv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Chiinv.java new file mode 100644 index 0000000000..c2d45b0e6e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Chiinv.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Chiinv extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Chitest.java b/src/java/org/apache/poi/hssf/record/formula/functions/Chitest.java new file mode 100644 index 0000000000..b7065b0ea6 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Chitest.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Chitest extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Choose.java b/src/java/org/apache/poi/hssf/record/formula/functions/Choose.java new file mode 100644 index 0000000000..e7acc93c48 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Choose.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Choose extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Clean.java b/src/java/org/apache/poi/hssf/record/formula/functions/Clean.java new file mode 100644 index 0000000000..cc01655d57 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Clean.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Clean extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Code.java b/src/java/org/apache/poi/hssf/record/formula/functions/Code.java new file mode 100644 index 0000000000..e340a5757d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Code.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Code extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Column.java b/src/java/org/apache/poi/hssf/record/formula/functions/Column.java new file mode 100644 index 0000000000..adde35c162 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Column.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.AreaEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Column implements Function { + public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + int cnum = -1; + + switch (evals.length) { + default: + retval = ErrorEval.VALUE_INVALID; + case 1: + if (evals[0] instanceof AreaEval) { + AreaEval ae = (AreaEval) evals[0]; + cnum = ae.getFirstColumn(); + } + else if (evals[0] instanceof RefEval) { + RefEval re = (RefEval) evals[0]; + cnum = re.getColumn(); + } + else { // anything else is not valid argument + retval = ErrorEval.VALUE_INVALID; + } + break; + case 0: + cnum = srcCellCol; + } + + if (retval == null) { + retval = (cnum >= 0) + ? new NumberEval(cnum + 1) // +1 since excel colnums are 1 based + : (ValueEval) ErrorEval.VALUE_INVALID; + } + + return retval; + } + + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Columns.java b/src/java/org/apache/poi/hssf/record/formula/functions/Columns.java new file mode 100644 index 0000000000..b75864e72d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Columns.java @@ -0,0 +1,59 @@ +/* +* 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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; + +/** + * Implementation for Excel COLUMNS function. + * + * @author Josh Micich + */ +public final class Columns implements Function { + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + switch(args.length) { + case 1: + // expected + break; + case 0: + // too few arguments + return ErrorEval.VALUE_INVALID; + default: + // too many arguments + return ErrorEval.VALUE_INVALID; + } + Eval firstArg = args[0]; + + int result; + if (firstArg instanceof AreaEval) { + AreaEval ae = (AreaEval) firstArg; + result = ae.getLastColumn() - ae.getFirstColumn() + 1; + } else if (firstArg 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/Combin.java b/src/java/org/apache/poi/hssf/record/formula/functions/Combin.java new file mode 100644 index 0000000000..72d6d4691e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Combin.java @@ -0,0 +1,87 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Combin extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d0 = 0; + double d1 = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d0 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + if (retval == null) { + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d1 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + if (d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) { + retval = ErrorEval.NUM_ERROR; + } + else { + double d = MathX.nChooseK((int) d0, (int) d1); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Concatenate.java b/src/java/org/apache/poi/hssf/record/formula/functions/Concatenate.java new file mode 100644 index 0000000000..be961c151e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Concatenate.java @@ -0,0 +1,60 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.StringValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Concatenate extends TextFunction { + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + StringBuffer sb = new StringBuffer(); + + for (int i=0, iSize=operands.length; i 30) { + // too many arguments + return ErrorEval.VALUE_INVALID; + } + + int temp = 0; + // Note - observed behavior of Excel: + // Error values like #VALUE!, #REF!, #DIV/0!, #NAME? etc don't cause this COUNTA to return an error + // in fact, they seem to get counted + + for(int i=0; i + * + * Syntax: COUNTIF ( range, criteria ) + * + * + * + *
    range   is the range of cells to be counted based on the criteria
    criteriais used to determine which cells to count
    + *

    + * + * @author Josh Micich + */ +public final class Countif implements Function { + + /** + * Common interface for the matching criteria. + */ + private interface I_MatchPredicate { + boolean matches(Eval x); + } + + private static final class NumberMatcher implements I_MatchPredicate { + + private final double _value; + + public NumberMatcher(double value) { + _value = value; + } + + public boolean matches(Eval x) { + if(x instanceof StringEval) { + // if the target(x) is a string, but parses as a number + // it may still count as a match + StringEval se = (StringEval)x; + Double val = parseDouble(se.getStringValue()); + if(val == null) { + // x is text that is not a number + return false; + } + return val.doubleValue() == _value; + } + if(!(x instanceof NumberEval)) { + return false; + } + NumberEval ne = (NumberEval) x; + return ne.getNumberValue() == _value; + } + } + private static final class BooleanMatcher implements I_MatchPredicate { + + private final boolean _value; + + public BooleanMatcher(boolean value) { + _value = value; + } + + public boolean matches(Eval x) { + if(x instanceof StringEval) { + StringEval se = (StringEval)x; + Boolean val = parseBoolean(se.getStringValue()); + if(val == null) { + // x is text that is not a boolean + return false; + } + if (true) { // change to false to observe more intuitive behaviour + // Note - Unlike with numbers, it seems that COUNTA never matches + // boolean values when the target(x) is a string + return false; + } + return val.booleanValue() == _value; + } + if(!(x instanceof BoolEval)) { + return false; + } + BoolEval be = (BoolEval) x; + return be.getBooleanValue() == _value; + } + } + private static final class StringMatcher implements I_MatchPredicate { + + private final String _value; + + public StringMatcher(String value) { + _value = value; + } + + public boolean matches(Eval x) { + if(!(x instanceof StringEval)) { + return false; + } + StringEval se = (StringEval) x; + return se.getStringValue() == _value; + } + } + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + switch(args.length) { + case 2: + // expected + break; + default: + // TODO - it doesn't seem to be possible to enter COUNTIF() into Excel with the wrong arg count + // perhaps this should be an exception + return ErrorEval.VALUE_INVALID; + } + + AreaEval range = (AreaEval) args[0]; + Eval criteriaArg = args[1]; + if(criteriaArg instanceof RefEval) { + // criteria is not a literal value, but a cell reference + // for example COUNTIF(B2:D4, E1) + RefEval re = (RefEval)criteriaArg; + criteriaArg = re.getInnerValueEval(); + } else { + // other non literal tokens such as function calls, have been fully evaluated + // for example COUNTIF(B2:D4, COLUMN(E1)) + } + I_MatchPredicate mp = createCriteriaPredicate(criteriaArg); + return countMatchingCellsInArea(range, mp); + } + /** + * @return the number of evaluated cells in the range that match the specified criteria + */ + private Eval countMatchingCellsInArea(AreaEval range, I_MatchPredicate criteriaPredicate) { + ValueEval[] values = range.getValues(); + int result = 0; + for (int i = 0; i < values.length; i++) { + if(criteriaPredicate.matches(values[i])) { + result++; + } + } + return new NumberEval(result); + } + + private static I_MatchPredicate createCriteriaPredicate(Eval evaluatedCriteriaArg) { + if(evaluatedCriteriaArg instanceof NumberEval) { + return new NumberMatcher(((NumberEval)evaluatedCriteriaArg).getNumberValue()); + } + if(evaluatedCriteriaArg instanceof BoolEval) { + return new BooleanMatcher(((BoolEval)evaluatedCriteriaArg).getBooleanValue()); + } + + if(evaluatedCriteriaArg instanceof StringEval) { + return createGeneralMatchPredicate((StringEval)evaluatedCriteriaArg); + } + throw new RuntimeException("Unexpected type for criteria (" + + evaluatedCriteriaArg.getClass().getName() + ")"); + } + + /** + * When the second argument is a string, many things are possible + */ + private static I_MatchPredicate createGeneralMatchPredicate(StringEval stringEval) { + String value = stringEval.getStringValue(); + char firstChar = value.charAt(0); + Boolean booleanVal = parseBoolean(value); + if(booleanVal != null) { + return new BooleanMatcher(booleanVal.booleanValue()); + } + + Double doubleVal = parseDouble(value); + if(doubleVal != null) { + return new NumberMatcher(doubleVal.doubleValue()); + } + switch(firstChar) { + case '>': + case '<': + case '=': + throw new RuntimeException("Incomplete code - criteria expressions such as '" + + value + "' not supported yet"); + } + + //else - just a plain string with no interpretation. + return new StringMatcher(value); + } + + /** + * Under certain circumstances COUNTA will equate a plain number with a string representation of that number + */ + /* package */ static Double parseDouble(String strRep) { + if(!Character.isDigit(strRep.charAt(0))) { + // avoid using NumberFormatException to tell when string is not a number + return null; + } + // TODO - support notation like '1E3' (==1000) + + double val; + try { + val = Double.parseDouble(strRep); + } catch (NumberFormatException e) { + return null; + } + return new Double(val); + } + /** + * Boolean literals ('TRUE', 'FALSE') treated similarly but NOT same as numbers. + */ + /* package */ static Boolean parseBoolean(String strRep) { + switch(strRep.charAt(0)) { + case 't': + case 'T': + if("TRUE".equalsIgnoreCase(strRep)) { + return Boolean.TRUE; + } + break; + case 'f': + case 'F': + if("FALSE".equalsIgnoreCase(strRep)) { + return Boolean.FALSE; + } + break; + } + return null; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Covar.java b/src/java/org/apache/poi/hssf/record/formula/functions/Covar.java new file mode 100644 index 0000000000..fc1188992d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Covar.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Covar extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Critbinom.java b/src/java/org/apache/poi/hssf/record/formula/functions/Critbinom.java new file mode 100644 index 0000000000..3a3d1a67b9 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Critbinom.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Critbinom extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Customrepeat.java b/src/java/org/apache/poi/hssf/record/formula/functions/Customrepeat.java new file mode 100644 index 0000000000..4206a173fa --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Customrepeat.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Customrepeat extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Date.java b/src/java/org/apache/poi/hssf/record/formula/functions/Date.java new file mode 100644 index 0000000000..6861a02524 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Date.java @@ -0,0 +1,114 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package org.apache.poi.hssf.record.formula.functions; + +import java.util.Calendar; +import java.util.GregorianCalendar; + +import org.apache.poi.hssf.usermodel.HSSFDateUtil; + +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +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.ValueEval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; + +/** + * @author Pavel Krupets (pkrupets at palmtreebusiness dot com) + */ +public class Date extends NumericFunction { + /** + * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) + */ + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + if (operands.length == 3) { + ValueEval ve[] = new ValueEval[3]; + + ve[0] = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + ve[1] = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); + ve[2] = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol); + + if (validValues(ve)) { + int year = getYear(ve[0]); + int month = (int) ((NumericValueEval) ve[1]).getNumberValue() - 1; + int day = (int) ((NumericValueEval) ve[2]).getNumberValue(); + + if (year < 0 || month < 0 || day < 0) { + return ErrorEval.VALUE_INVALID; + } + + if (year == 1900 && month == Calendar.FEBRUARY && day == 29) { + return new NumberEval(60.0); + } + + if (year == 1900) { + if ((month == Calendar.JANUARY && day >= 60) || + (month == Calendar.FEBRUARY && day >= 30)) + { + day--; + } + } + + Calendar c = new GregorianCalendar(); + + c.set(year, month, day, 0, 0, 0); + c.set(Calendar.MILLISECOND, 0); + + return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime(), false)); // XXX fix 1900/1904 problem + } + } + + return ErrorEval.VALUE_INVALID; + } + + private int getYear(ValueEval ve) { + int year = (int) ((NumericValueEval) ve).getNumberValue(); + + if (year < 0) { + return -1; + } + + return year < 1900 ? 1900 + year : year; + } + + private boolean validValues(ValueEval[] values) { + for (int i = 0; i < values.length; i++) { + ValueEval value = values[i]; + + if (value instanceof RefEval) { + RefEval re = (RefEval) value; + ValueEval ive = re.getInnerValueEval(); + + if (ive instanceof BlankEval) { + value = new NumberEval(0); + } else if (ive instanceof NumericValueEval) { + value = ive; + } else { + return false; + } + } + + if (!(value instanceof NumericValueEval)) { + return false; + } + } + + return true; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Datedif.java b/src/java/org/apache/poi/hssf/record/formula/functions/Datedif.java new file mode 100644 index 0000000000..1a14516049 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Datedif.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Datedif extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Datestring.java b/src/java/org/apache/poi/hssf/record/formula/functions/Datestring.java new file mode 100644 index 0000000000..0a80110b79 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Datestring.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Datestring extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Datevalue.java b/src/java/org/apache/poi/hssf/record/formula/functions/Datevalue.java new file mode 100644 index 0000000000..a0377527cf --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Datevalue.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Datevalue extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Daverage.java b/src/java/org/apache/poi/hssf/record/formula/functions/Daverage.java new file mode 100644 index 0000000000..ebf9c28bce --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Daverage.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Daverage extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Day.java b/src/java/org/apache/poi/hssf/record/formula/functions/Day.java new file mode 100644 index 0000000000..0ae5694767 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Day.java @@ -0,0 +1,64 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.usermodel.HSSFDateUtil; + +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; + +/** + * @author Pavel Krupets + */ +public class Day extends NumericFunction { + /** + * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) + */ + public Eval evaluate(Eval[] operands, int srcCellRow, short +srcCellCol) { + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], +srcCellRow, srcCellCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { + java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem + java.util.Calendar c = java.util.Calendar.getInstance(); + c.setTime(d); + retval = new NumberEval(c.get(java.util.Calendar.DAY_OF_MONTH)); + } else { + retval = ErrorEval.NUM_ERROR; + } + } else if (ve instanceof BlankEval) { + // do nothing + } else { + retval = ErrorEval.NUM_ERROR; + } + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Days360.java b/src/java/org/apache/poi/hssf/record/formula/functions/Days360.java new file mode 100644 index 0000000000..2187576429 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Days360.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Days360 extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Db.java b/src/java/org/apache/poi/hssf/record/formula/functions/Db.java new file mode 100644 index 0000000000..1dd80b6af7 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Db.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Db extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dbcs.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dbcs.java new file mode 100644 index 0000000000..30ad221bcf --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dbcs.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dbcs extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dcount.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dcount.java new file mode 100644 index 0000000000..1d64ae2595 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dcount.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dcount extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dcounta.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dcounta.java new file mode 100644 index 0000000000..72d36bc0fd --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dcounta.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dcounta extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ddb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ddb.java new file mode 100644 index 0000000000..66b5a33e08 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ddb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Ddb extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java b/src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java new file mode 100644 index 0000000000..e85e14d567 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Degrees.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Degrees extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.toDegrees(d); + retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Deref.java b/src/java/org/apache/poi/hssf/record/formula/functions/Deref.java new file mode 100644 index 0000000000..bb773522b2 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Deref.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Deref extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Devsq.java b/src/java/org/apache/poi/hssf/record/formula/functions/Devsq.java new file mode 100644 index 0000000000..a198ff8398 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Devsq.java @@ -0,0 +1,77 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Devsq extends MultiOperandNumericFunction { + + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) (0 + | ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED + )); + + /** + * this is the default impl for the factory method getXlator + * of the super class NumericFunction. Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = StatsLib.devsq(values); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dget.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dget.java new file mode 100644 index 0000000000..ebd846333b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dget.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dget extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dmax.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dmax.java new file mode 100644 index 0000000000..18ea2bdc7b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dmax.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dmax extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dmin.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dmin.java new file mode 100644 index 0000000000..9307af584a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dmin.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dmin extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java new file mode 100644 index 0000000000..a65f65a3e7 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dollar.java @@ -0,0 +1,64 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Dollar extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dproduct.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dproduct.java new file mode 100644 index 0000000000..bf86748d2c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dproduct.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dproduct extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dstdev.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dstdev.java new file mode 100644 index 0000000000..0cdb4c237f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dstdev.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dstdev extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dstdevp.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dstdevp.java new file mode 100644 index 0000000000..e9a2bfaf13 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dstdevp.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dstdevp extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dsum.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dsum.java new file mode 100644 index 0000000000..3c057ca28b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dsum.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dsum extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dvar.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dvar.java new file mode 100644 index 0000000000..764cf618c4 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dvar.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dvar extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Dvarp.java b/src/java/org/apache/poi/hssf/record/formula/functions/Dvarp.java new file mode 100644 index 0000000000..03928b77d4 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Dvarp.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Dvarp extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Echo.java b/src/java/org/apache/poi/hssf/record/formula/functions/Echo.java new file mode 100644 index 0000000000..87d4e29bf8 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Echo.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Echo extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Error.java b/src/java/org/apache/poi/hssf/record/formula/functions/Error.java new file mode 100644 index 0000000000..41a7ecd9d4 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Error.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Error extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Errortype.java b/src/java/org/apache/poi/hssf/record/formula/functions/Errortype.java new file mode 100644 index 0000000000..51268c9aa0 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Errortype.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Errortype extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Evaluate.java b/src/java/org/apache/poi/hssf/record/formula/functions/Evaluate.java new file mode 100644 index 0000000000..d458875406 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Evaluate.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Evaluate extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Even.java b/src/java/org/apache/poi/hssf/record/formula/functions/Even.java new file mode 100644 index 0000000000..9149671676 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Even.java @@ -0,0 +1,73 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Even extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + if (!Double.isNaN(d) && !Double.isInfinite(d)) { + d = (d==0) + ? 0 + : (((long) (d/2))*2 == d) + ? d + : (d < 0) + ? ((((long) (d/2))<<1)-2) + : ((((long) (d/2))<<1)+2); + } + retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Exact.java b/src/java/org/apache/poi/hssf/record/formula/functions/Exact.java new file mode 100644 index 0000000000..63dc18d771 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Exact.java @@ -0,0 +1,84 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.StringValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Exact extends TextFunction { + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + String s0 = null; + String s1 = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + if (ve instanceof StringValueEval) { + StringValueEval sve = (StringValueEval) ve; + s0 = sve.getStringValue(); + } + else if (ve instanceof BlankEval) { + s0 = StringEval.EMPTY_INSTANCE.getStringValue(); + } + else { + retval = ErrorEval.VALUE_INVALID; + break; + } + + if (retval == null) { + ve = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); + if (ve instanceof StringValueEval) { + StringValueEval sve = (StringValueEval) ve; + s1 = sve.getStringValue(); + } + else if (ve instanceof BlankEval) { + s1 = StringEval.EMPTY_INSTANCE.getStringValue(); + } + else { + retval = ErrorEval.VALUE_INVALID; + break; + } + } + } + + if (retval == null) { + boolean b = s0.equals(s1); + retval = b ? BoolEval.TRUE : BoolEval.FALSE; + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Exec.java b/src/java/org/apache/poi/hssf/record/formula/functions/Exec.java new file mode 100644 index 0000000000..327ba77f4e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Exec.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Exec extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Exp.java b/src/java/org/apache/poi/hssf/record/formula/functions/Exp.java new file mode 100644 index 0000000000..d0b122ab16 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Exp.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Exp extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.pow(E, d); + retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Expondist.java b/src/java/org/apache/poi/hssf/record/formula/functions/Expondist.java new file mode 100644 index 0000000000..5ba8727d9d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Expondist.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Expondist extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fact.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fact.java new file mode 100644 index 0000000000..128b167c65 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Fact.java @@ -0,0 +1,74 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 22, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Fact extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + if (d < Integer.MAX_VALUE && d >= 0) { + d = MathX.factorial((int) d); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : (Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/False.java b/src/java/org/apache/poi/hssf/record/formula/functions/False.java new file mode 100644 index 0000000000..2a16b1c73a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/False.java @@ -0,0 +1,46 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class False implements Function { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval; + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 0: + retval = BoolEval.FALSE; + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fdist.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fdist.java new file mode 100644 index 0000000000..be27363247 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Fdist.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Fdist extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Files.java b/src/java/org/apache/poi/hssf/record/formula/functions/Files.java new file mode 100644 index 0000000000..156fc67012 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Files.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Files extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java new file mode 100644 index 0000000000..c054c6dac4 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java @@ -0,0 +1,71 @@ +/* +* 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.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * Super class for all Evals for financial function evaluation. + * + */ +public abstract class FinanceFunction extends NumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) (0 + | ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + | ValueEvalToNumericXlator.BLANK_IS_PARSED + | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + )); + + /** + * this is the default impl of the factory(ish) method getXlator. + * Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected final ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + protected final ValueEval singleOperandNumericAsBoolean(Eval eval, int srcRow, short srcCol) { + ValueEval retval = null; + retval = singleOperandEvaluate(eval, srcRow, srcCol); + if (retval instanceof NumericValueEval) { + NumericValueEval nve = (NumericValueEval) retval; + retval = (nve.getNumberValue() == 0) + ? BoolEval.FALSE + : BoolEval.TRUE; + } + else { + retval = ErrorEval.VALUE_INVALID; + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/FinanceLib.java b/src/java/org/apache/poi/hssf/record/formula/functions/FinanceLib.java new file mode 100644 index 0000000000..96f8717a2c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/FinanceLib.java @@ -0,0 +1,190 @@ +/* +* 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 21, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + * + * This class is a functon library for common fiscal functions. + * Glossary of terms/abbreviations: + *
    + *

      + *
    • FV: Future Value
    • + *
    • PV: Present Value
    • + *
    • NPV: Net Present Value
    • + *
    • PMT: (Periodic) Payment
    • + * + *
    + * For more info on the terms/abbreviations please use the references below + * (hyperlinks are subject to change): + *
    Online References: + *
      + *
    1. GNU Emacs Calc 2.02 Manual: http://theory.uwinnipeg.ca/gnu/calc/calc_203.html
    2. + *
    3. Yahoo Financial Glossary: http://biz.yahoo.com/f/g/nn.html#y
    4. + *
    5. MS Excel function reference: http://office.microsoft.com/en-us/assistance/CH062528251033.aspx
    6. + *
    + *

    Implementation Notes:

    + * Symbols used in the formulae that follow:
    + *
      + *
    • p: present value
    • + *
    • f: future value
    • + *
    • n: number of periods
    • + *
    • y: payment (in each period)
    • + *
    • r: rate
    • + *
    • ^: the power operator (NOT the java bitwise XOR operator!)
    • + *
    + * [From MS Excel function reference] Following are some of the key formulas + * that are used in this implementation: + *
    + * p(1+r)^n + y(1+rt)((1+r)^n-1)/r + f=0   ...{when r!=0}
    + * ny + p + f=0                            ...{when r=0}
    + * 
    + */ +public final class FinanceLib { + + // constants for default values + + + + private FinanceLib() {} + + /** + * 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 + * Two important functions with this feature are INDIRECT and OFFSET

    + * + * In POI, the HSSFFormulaEvaluator evaluates every cell in each reference argument before + * calling the function. This means that functions using fixed references do not need access to + * the rest of the workbook to execute. Hence the evaluate() method on the common + * interface Function does not take a workbook parameter.

    + * + * This interface recognises the requirement of some functions to freely create and evaluate + * references beyond those passed in as arguments. + * + * @author Josh Micich + */ +public interface FreeRefFunction { + /** + * + * @param args the pre-evaluated arguments for this function. args is never null, + * nor are any of its elements. + * @param srcCellRow zero based row index of the cell containing the currently evaluating formula + * @param srcCellCol zero based column index of the cell containing the currently evaluating formula + * @param workbook is the workbook containing the formula/cell being evaluated + * @param sheet is the sheet containing the formula/cell being evaluated + * @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(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet); +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Frequency.java b/src/java/org/apache/poi/hssf/record/formula/functions/Frequency.java new file mode 100644 index 0000000000..fc003c3e2e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Frequency.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Frequency extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ftest.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ftest.java new file mode 100644 index 0000000000..fb662027ef --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ftest.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Ftest extends NotImplementedFunction { + +} 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 new file mode 100644 index 0000000000..e33514a463 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Function.java @@ -0,0 +1,33 @@ +/* +* 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 9, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.Eval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * Function serves as a marker interface. + */ +public interface Function { + + public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol); + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Fv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Fv.java new file mode 100644 index 0000000000..fd0335c388 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Fv.java @@ -0,0 +1,75 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Fv extends FinanceFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double rate = 0, nper = 0, pmt = 0, pv = 0, d = 0; + boolean type = false; + ValueEval retval = null; + ValueEval ve = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 5: + ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol); + if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; } + type = ((BoolEval) ve).getBooleanValue(); + case 4: + ve = singleOperandEvaluate(operands[3], srcRow, srcCol); + if (ve instanceof NumericValueEval) pv = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + case 3: + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) nper = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + + ve = singleOperandEvaluate(operands[2], srcRow, srcCol); + if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + + ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + } + + if (retval == null) { + d = FinanceLib.fv(rate, nper, pmt, pv, type); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : (Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Gammadist.java b/src/java/org/apache/poi/hssf/record/formula/functions/Gammadist.java new file mode 100644 index 0000000000..fa788c55e5 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Gammadist.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Gammadist extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Gammainv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Gammainv.java new file mode 100644 index 0000000000..ea8bdc53be --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Gammainv.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Gammainv extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Gammaln.java b/src/java/org/apache/poi/hssf/record/formula/functions/Gammaln.java new file mode 100644 index 0000000000..fb6026657a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Gammaln.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Gammaln extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Geomean.java b/src/java/org/apache/poi/hssf/record/formula/functions/Geomean.java new file mode 100644 index 0000000000..1669a78901 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Geomean.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Geomean extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Goto.java b/src/java/org/apache/poi/hssf/record/formula/functions/Goto.java new file mode 100644 index 0000000000..c1a4d596da --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Goto.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Goto extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Group.java b/src/java/org/apache/poi/hssf/record/formula/functions/Group.java new file mode 100644 index 0000000000..91c6cc5d18 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Group.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Group extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Growth.java b/src/java/org/apache/poi/hssf/record/formula/functions/Growth.java new file mode 100644 index 0000000000..5a35a2b24b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Growth.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Growth extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Halt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Halt.java new file mode 100644 index 0000000000..74ce5761c6 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Halt.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Halt extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Harmean.java b/src/java/org/apache/poi/hssf/record/formula/functions/Harmean.java new file mode 100644 index 0000000000..ade3109a1b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Harmean.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Harmean extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Help.java b/src/java/org/apache/poi/hssf/record/formula/functions/Help.java new file mode 100644 index 0000000000..1bf4004ac1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Help.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Help extends NotImplementedFunction { + +} 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 new file mode 100644 index 0000000000..40ed1da490 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Hlookup.java @@ -0,0 +1,123 @@ +/* ==================================================================== + 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.Eval; +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; +/** + * Implementation of the VLOOKUP() function.

    + * + * HLOOKUP finds a column in a lookup table by the first row value and returns the value from another row. + * + * Syntax:
    + * HLOOKUP(lookup_value, table_array, row_index_num, range_lookup)

    + * + * lookup_value The value to be found in the first column of the table array.
    + * table_array An area reference for the lookup data.
    + * row_index_num a 1 based index specifying which row value of the lookup data will be returned.
    + * range_lookup If TRUE (default), HLOOKUP finds the largest value less than or equal to + * the lookup_value. If FALSE, only exact matches will be considered
    + * + * @author Josh Micich + */ +public final class Hlookup implements Function { + + private static final class RowVector implements ValueVector { + + private final AreaEval _tableArray; + private final int _size; + private final int _rowAbsoluteIndex; + private final int _firstColumnAbsoluteIndex; + + public RowVector(AreaEval tableArray, int rowIndex) { + _rowAbsoluteIndex = tableArray.getFirstRow() + rowIndex; + if(!tableArray.containsRow(_rowAbsoluteIndex)) { + int lastRowIx = tableArray.getLastRow() - tableArray.getFirstRow(); + throw new IllegalArgumentException("Specified row index (" + rowIndex + + ") is outside the allowed range (0.." + lastRowIx + ")"); + } + _tableArray = tableArray; + _size = tableArray.getLastColumn() - tableArray.getFirstColumn() + 1; + if(_size < 1) { + throw new RuntimeException("bad table array size zero"); + } + _firstColumnAbsoluteIndex = tableArray.getFirstColumn(); + } + + public ValueEval getItem(int index) { + if(index>_size) { + throw new ArrayIndexOutOfBoundsException("Specified index (" + index + + ") is outside the allowed range (0.." + (_size-1) + ")"); + } + return _tableArray.getValueAt(_rowAbsoluteIndex, (short) (_firstColumnAbsoluteIndex + index)); + } + public int getSize() { + return _size; + } + } + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + Eval arg3 = null; + switch(args.length) { + case 4: + arg3 = args[3]; // important: assumed array element is never null + case 3: + break; + default: + // wrong number of arguments + return ErrorEval.VALUE_INVALID; + } + try { + // Evaluation order: + // arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 row_index, fetch result + ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + AreaEval tableArray = LookupUtils.resolveTableArrayArg(args[1]); + boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcCellRow, srcCellCol); + int colIndex = LookupUtils.lookupIndexOfValue(lookupValue, new RowVector(tableArray, 0), isRangeLookup); + ValueEval veColIndex = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol); + int rowIndex = LookupUtils.resolveRowOrColIndexArg(veColIndex); + ValueVector resultCol = createResultColumnVector(tableArray, rowIndex); + return resultCol.getItem(colIndex); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + } + + + /** + * Returns one column from an AreaEval + * + * @throws EvaluationException (#VALUE!) if colIndex is negative, (#REF!) if colIndex is too high + */ + private ValueVector createResultColumnVector(AreaEval tableArray, int colIndex) throws EvaluationException { + if(colIndex < 0) { + throw EvaluationException.invalidValue(); + } + int nCols = tableArray.getLastColumn() - tableArray.getFirstRow() + 1; + + if(colIndex >= nCols) { + throw EvaluationException.invalidRef(); + } + return new RowVector(tableArray, colIndex); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Hour.java b/src/java/org/apache/poi/hssf/record/formula/functions/Hour.java new file mode 100644 index 0000000000..0caeda4d8c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Hour.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Hour extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Hyperlink.java b/src/java/org/apache/poi/hssf/record/formula/functions/Hyperlink.java new file mode 100644 index 0000000000..020d40d87f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Hyperlink.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Hyperlink extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Hypgeomdist.java b/src/java/org/apache/poi/hssf/record/formula/functions/Hypgeomdist.java new file mode 100644 index 0000000000..9c76cc148a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Hypgeomdist.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Hypgeomdist extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/If.java b/src/java/org/apache/poi/hssf/record/formula/functions/If.java new file mode 100644 index 0000000000..7aba5db72a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/If.java @@ -0,0 +1,49 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on Nov 25, 2006 + * + */ +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.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class If implements Function { + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + + Eval evalWhenFalse = BoolEval.FALSE; + switch (args.length) { + case 3: + evalWhenFalse = args[2]; + case 2: + BoolEval beval = (BoolEval) args[0]; // TODO - class cast exception + if (beval.getBooleanValue()) { + return args[1]; + } + return evalWhenFalse; + default: + return ErrorEval.VALUE_INVALID; + } + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Index.java b/src/java/org/apache/poi/hssf/record/formula/functions/Index.java new file mode 100644 index 0000000000..aebf6aab0d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Index.java @@ -0,0 +1,108 @@ +/* +* 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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; + +/** + * Implementation for the Excel function INDEX

    + * + * Syntax :
    + * INDEX ( reference, row_num[, column_num [, area_num]])
    + * INDEX ( array, row_num[, column_num]) + * + * + * + * + * + * + *
    referencetypically an area reference, possibly a union of areas
    arraya literal array value (currently not supported)
    row_numselects the row within the array or area reference
    column_numselects column within the array or area reference. default is 1
    area_numused when reference is a union of areas
    + *

    + * + * @author Josh Micich + */ +public final class Index implements Function { + + // TODO - javadoc for interface method + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + int nArgs = args.length; + if(nArgs < 2) { + // too few arguments + return ErrorEval.VALUE_INVALID; + } + Eval firstArg = args[0]; + if(firstArg instanceof AreaEval) { + AreaEval reference = (AreaEval) firstArg; + + int rowIx = 0; + int columnIx = 0; + int areaIx = 0; + switch(nArgs) { + case 4: + areaIx = convertIndexArgToZeroBase(args[3]); + throw new RuntimeException("Incomplete code" + + " - don't know how to support the 'area_num' parameter yet)"); + // Excel expression might look like this "INDEX( (A1:B4, C3:D6, D2:E5 ), 1, 2, 3) + // In this example, the 3rd area would be used i.e. D2:E5, and the overall result would be E2 + // Token array might be encoded like this: MemAreaPtg, AreaPtg, AreaPtg, UnionPtg, UnionPtg, ParenthesesPtg + // The formula parser doesn't seem to support this yet. Not sure if the evaluator does either + + case 3: + columnIx = convertIndexArgToZeroBase(args[2]); + case 2: + rowIx = convertIndexArgToZeroBase(args[1]); + break; + default: + // too many arguments + return ErrorEval.VALUE_INVALID; + } + + int nColumns = reference.getLastColumn()-reference.getFirstColumn()+1; + int index = rowIx * nColumns + columnIx; + + return reference.getValues()[index]; + } + + // else the other variation of this function takes an array as the first argument + // it seems like interface 'ArrayEval' does not even exist yet + + throw new RuntimeException("Incomplete code - cannot handle first arg of type (" + + firstArg.getClass().getName() + ")"); + } + + /** + * takes a NumberEval representing a 1-based index and returns the zero-based int value + */ + private static int convertIndexArgToZeroBase(Eval ev) { + NumberEval ne; + if(ev instanceof RefEval) { + // TODO - write junit to justify this + RefEval re = (RefEval) ev; + ne = (NumberEval) re.getInnerValueEval(); + } else { + ne = (NumberEval)ev; + } + + return (int)ne.getNumberValue() - 1; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java b/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java new file mode 100644 index 0000000000..935e7cdbbd --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Indirect.java @@ -0,0 +1,49 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Implementation for Excel function INDIRECT

    + * + * INDIRECT() returns the cell or area reference denoted by the text argument.

    + * + * Syntax:
    + * INDIRECT(ref_text,isA1Style)

    + * + * ref_text a string representation of the desired reference as it would normally be written + * in a cell formula.
    + * isA1Style (default TRUE) specifies whether the ref_text should be interpreted as A1-style + * or R1C1-style. + * + * + * @author Josh Micich + */ +public final class Indirect implements FreeRefFunction { + + public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { + // TODO - implement INDIRECT() + return ErrorEval.FUNCTION_NOT_IMPLEMENTED; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Info.java b/src/java/org/apache/poi/hssf/record/formula/functions/Info.java new file mode 100644 index 0000000000..2b542dd717 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Info.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Info extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Initiate.java b/src/java/org/apache/poi/hssf/record/formula/functions/Initiate.java new file mode 100644 index 0000000000..6795c7aeb1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Initiate.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Initiate extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Input.java b/src/java/org/apache/poi/hssf/record/formula/functions/Input.java new file mode 100644 index 0000000000..0d3614c796 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Input.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Input extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Int.java b/src/java/org/apache/poi/hssf/record/formula/functions/Int.java new file mode 100644 index 0000000000..5b26a8a8a1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Int.java @@ -0,0 +1,69 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Int extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + if (d < 0) { + d = Math.round(d-0.5); + } + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval((long) d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Intercept.java b/src/java/org/apache/poi/hssf/record/formula/functions/Intercept.java new file mode 100644 index 0000000000..bf94b5ba29 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Intercept.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Intercept extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ipmt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ipmt.java new file mode 100644 index 0000000000..61e85a4d5b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ipmt.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Ipmt extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Irr.java b/src/java/org/apache/poi/hssf/record/formula/functions/Irr.java new file mode 100644 index 0000000000..f23325e4f9 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Irr.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Irr extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/IsError.java b/src/java/org/apache/poi/hssf/record/formula/functions/IsError.java new file mode 100644 index 0000000000..786060704e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/IsError.java @@ -0,0 +1,96 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.AreaEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class IsError implements Function { + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + boolean b = false; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + if (operands[0] instanceof ErrorEval) { + b = true; + } + else if (operands[0] instanceof AreaEval) { + AreaEval ae = (AreaEval) operands[0]; + if (ae.contains(srcCellRow, srcCellCol)) { // circular ref! + retval = ErrorEval.CIRCULAR_REF_ERROR; + } + else if (ae.isRow()) { + if (ae.containsColumn(srcCellCol)) { + ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCellCol); + if (ve instanceof RefEval) + b = ((RefEval) ve).getInnerValueEval() instanceof ErrorEval; + else + b = (ve instanceof ErrorEval); + } + else { + b = true; + } + } + else if (ae.isColumn()) { + if (ae.containsRow(srcCellRow)) { + ValueEval ve = ae.getValueAt(srcCellRow, ae.getFirstColumn()); + if (ve instanceof RefEval) + b = ((RefEval) ve).getInnerValueEval() instanceof ErrorEval; + else + b = (ve instanceof ErrorEval); + } + else { + b = true; + } + } + else { + b = true; + } + } + else if (operands[0] instanceof RefEval) { + b = ((RefEval) operands[0]).getInnerValueEval() instanceof ErrorEval; + } + else { + b = false; + } + } + + if (retval == null) { + retval = b + ? BoolEval.TRUE + : BoolEval.FALSE; + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/IsNa.java b/src/java/org/apache/poi/hssf/record/formula/functions/IsNa.java new file mode 100644 index 0000000000..b1f8f09641 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/IsNa.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class IsNa extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Isblank.java b/src/java/org/apache/poi/hssf/record/formula/functions/Isblank.java new file mode 100644 index 0000000000..c0e482e5a8 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Isblank.java @@ -0,0 +1,48 @@ +/* +* 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.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.OperandResolver; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class Isblank implements Function { + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + if(args.length != 1) { + return ErrorEval.VALUE_INVALID; + } + Eval arg = args[0]; + + ValueEval singleCellValue; + try { + singleCellValue = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); + } catch (EvaluationException e) { + return BoolEval.FALSE; + } + return BoolEval.valueOf(singleCellValue instanceof BlankEval); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Iserr.java b/src/java/org/apache/poi/hssf/record/formula/functions/Iserr.java new file mode 100644 index 0000000000..f1ebd48fbd --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Iserr.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Iserr extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Islogical.java b/src/java/org/apache/poi/hssf/record/formula/functions/Islogical.java new file mode 100644 index 0000000000..318d1e69f1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Islogical.java @@ -0,0 +1,57 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Islogical extends LogicalFunction { + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = BoolEval.FALSE; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + Eval eval = operands[0]; + if (eval instanceof BoolEval) { + retval = BoolEval.TRUE; + } + else if (eval instanceof RefEval) { + Eval xlatedEval = xlateRefEval((RefEval) eval); + if (xlatedEval instanceof BoolEval) { + retval = BoolEval.TRUE; + } + } + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Isnontext.java b/src/java/org/apache/poi/hssf/record/formula/functions/Isnontext.java new file mode 100644 index 0000000000..eb07e63eb8 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Isnontext.java @@ -0,0 +1,56 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Isnontext extends LogicalFunction { + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = BoolEval.TRUE; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + Eval eval = operands[0]; + if (eval instanceof StringEval) { + retval = BoolEval.FALSE; + } + else if (eval instanceof RefEval) { + Eval xlatedEval = xlateRefEval((RefEval) eval); + if (xlatedEval instanceof StringEval) { + retval = BoolEval.FALSE; + } + } + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Isnumber.java b/src/java/org/apache/poi/hssf/record/formula/functions/Isnumber.java new file mode 100644 index 0000000000..e3ff8d49aa --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Isnumber.java @@ -0,0 +1,56 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Isnumber extends LogicalFunction { + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = BoolEval.FALSE; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + Eval eval = operands[0]; + if (eval instanceof NumberEval) { + retval = BoolEval.TRUE; + } + else if (eval instanceof RefEval) { + Eval xlatedEval = xlateRefEval((RefEval) eval); + if (xlatedEval instanceof NumberEval) { + retval = BoolEval.TRUE; + } + } + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ispmt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ispmt.java new file mode 100644 index 0000000000..69c7f428c3 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ispmt.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Ispmt extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Isref.java b/src/java/org/apache/poi/hssf/record/formula/functions/Isref.java new file mode 100644 index 0000000000..1deb606544 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Isref.java @@ -0,0 +1,50 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.AreaEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Isref implements Function { + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = BoolEval.FALSE; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + Eval eval = operands[0]; + if (eval instanceof RefEval || eval instanceof AreaEval) { + retval = BoolEval.TRUE; + } + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Istext.java b/src/java/org/apache/poi/hssf/record/formula/functions/Istext.java new file mode 100644 index 0000000000..ec87d79cbd --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Istext.java @@ -0,0 +1,56 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Istext extends LogicalFunction { + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = BoolEval.FALSE; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + Eval eval = operands[0]; + if (eval instanceof StringEval) { + retval = BoolEval.TRUE; + } + else if (eval instanceof RefEval) { + Eval xlatedEval = xlateRefEval((RefEval) eval); + if (xlatedEval instanceof StringEval) { + retval = BoolEval.TRUE; + } + } + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Kurt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Kurt.java new file mode 100644 index 0000000000..fe4e76eef5 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Kurt.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Kurt extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Large.java b/src/java/org/apache/poi/hssf/record/formula/functions/Large.java new file mode 100644 index 0000000000..3b9aed9768 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Large.java @@ -0,0 +1,81 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Large extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) (0 + | ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.BLANK_IS_PARSED + )); + + /** + * this is the default impl for the factory method getXlator + * of the super class NumericFunction. Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] ops = getNumberArray(operands, srcCellRow, srcCellCol); + if (ops == null || ops.length < 2) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double[] values = new double[ops.length-1]; + int k = (int) ops[ops.length-1]; + System.arraycopy(ops, 0, values, 0, values.length); + double d = StatsLib.kthLargest(values, k); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Lasterror.java b/src/java/org/apache/poi/hssf/record/formula/functions/Lasterror.java new file mode 100644 index 0000000000..c5024a5ad3 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Lasterror.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Lasterror extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Left.java b/src/java/org/apache/poi/hssf/record/formula/functions/Left.java new file mode 100644 index 0000000000..ecb14a7008 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Left.java @@ -0,0 +1,107 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.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 > + * + */ +public class Left extends TextFunction { + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = ErrorEval.VALUE_INVALID; + int index = 1; + switch (operands.length) { + default: + break; + case 2: + Eval indexEval = operands[1]; + index = evaluateAsInteger(indexEval); + if (index < 0) { + break; + } + case 1: + ValueEval veval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + String str = null; + if (veval instanceof StringEval) { + StringEval stringEval = (StringEval) veval; + str = stringEval.getStringValue(); + } + else if (veval instanceof BoolEval) { + BoolEval beval = (BoolEval) veval; + str = beval.getBooleanValue() ? "TRUE" : "FALSE"; + } + else if (veval instanceof NumberEval) { + NumberEval neval = (NumberEval) veval; + str = neval.getStringValue(); + } + if (null != str) { + str = str.substring(0, Math.min(str.length(), index)); + retval = new StringEval(str); + } + } + return retval; + } + + protected int evaluateAsInteger(Eval eval) { + int numval = -1; + if (eval instanceof NumberEval) { + NumberEval neval = (NumberEval) eval; + double d = neval.getNumberValue(); + numval = (int) d; + } + else if (eval instanceof StringEval) { + StringEval seval = (StringEval) eval; + String s = seval.getStringValue(); + try { + double d = Double.parseDouble(s); + numval = (int) d; + } + catch (Exception e) { + } + } + else if (eval instanceof BoolEval) { + BoolEval beval = (BoolEval) eval; + numval = beval.getBooleanValue() ? 1 : 0; + } + else if (eval instanceof RefEval) { + numval = evaluateAsInteger(xlateRefEval((RefEval) eval)); + } + return numval; + } + + protected Eval xlateRefEval(RefEval reval) { + Eval retval = reval.getInnerValueEval(); + + if (retval instanceof RefEval) { + retval = xlateRefEval((RefEval) retval); + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Leftb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Leftb.java new file mode 100644 index 0000000000..9c3d362970 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Leftb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Leftb extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Len.java b/src/java/org/apache/poi/hssf/record/formula/functions/Len.java new file mode 100644 index 0000000000..0bc49b4070 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Len.java @@ -0,0 +1,49 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.OperandResolver; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class Len extends TextFunction { + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + + if(args.length != 1) { + return ErrorEval.VALUE_INVALID; + } + + try { + ValueEval veval = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + + String str = OperandResolver.coerceValueToString(veval); + + return new NumberEval(str.length()); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Lenb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Lenb.java new file mode 100644 index 0000000000..b47105aa13 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Lenb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Lenb extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Linest.java b/src/java/org/apache/poi/hssf/record/formula/functions/Linest.java new file mode 100644 index 0000000000..ea415a40c1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Linest.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Linest extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Links.java b/src/java/org/apache/poi/hssf/record/formula/functions/Links.java new file mode 100644 index 0000000000..1f2d570204 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Links.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Links extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ln.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ln.java new file mode 100644 index 0000000000..95392a4d17 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ln.java @@ -0,0 +1,66 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Ln extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.log(d); + retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Log.java b/src/java/org/apache/poi/hssf/record/formula/functions/Log.java new file mode 100644 index 0000000000..7727c35275 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Log.java @@ -0,0 +1,87 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * Log: LOG(number,[base]) + */ +public class Log extends NumericFunction { + + private static final double DEFAULT_BASE = 10; + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + double base = DEFAULT_BASE; + double num = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: // second arg is base + ValueEval ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + base = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + case 1: // first arg is number + if (retval == null) { + ValueEval vev = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (vev instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) vev; + num = ne.getNumberValue(); + } + else if (vev instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + d = (base == E) + ? Math.log(num) + : Math.log(num) / Math.log(base); + retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Log10.java b/src/java/org/apache/poi/hssf/record/formula/functions/Log10.java new file mode 100644 index 0000000000..cf8b9bd138 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Log10.java @@ -0,0 +1,68 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Log10 extends NumericFunction { + private static final double LOG_10_TO_BASE_e = Math.log(10); + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.log(d) / LOG_10_TO_BASE_e; + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Logest.java b/src/java/org/apache/poi/hssf/record/formula/functions/Logest.java new file mode 100644 index 0000000000..2a36f7dad2 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Logest.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Logest extends NotImplementedFunction { + +} 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 new file mode 100644 index 0000000000..03756e1faf --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java @@ -0,0 +1,46 @@ +/* +* 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 Nov 25, 2006 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class LogicalFunction implements Function { + + /** + * recursively evaluate any RefEvals + * @param reval + */ + protected ValueEval xlateRefEval(RefEval reval) { + ValueEval retval = (ValueEval) reval.getInnerValueEval(); + + if (retval instanceof RefEval) { + RefEval re = (RefEval) retval; + retval = xlateRefEval(re); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Loginv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Loginv.java new file mode 100644 index 0000000000..8b885ca506 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Loginv.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Loginv extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Lognormdist.java b/src/java/org/apache/poi/hssf/record/formula/functions/Lognormdist.java new file mode 100644 index 0000000000..26ca53baec --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Lognormdist.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Lognormdist extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java b/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java new file mode 100644 index 0000000000..be1d0d0f94 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Lookup.java @@ -0,0 +1,96 @@ +/* ==================================================================== + 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.Eval; +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; + +/** + * Implementation of Excel function LOOKUP.

    + * + * LOOKUP finds an index row in a lookup table by the first column value and returns the value from another column. + * + * Syntax:
    + * VLOOKUP(lookup_value, lookup_vector, result_vector)

    + * + * lookup_value The value to be found in the lookup vector.
    + * lookup_vector An area reference for the lookup data.
    + * result_vector Single row or single column area reference from which the result value is chosen.
    + * + * @author Josh Micich + */ +public final class Lookup implements Function { + private static final class SimpleValueVector implements ValueVector { + private final ValueEval[] _values; + + public SimpleValueVector(ValueEval[] values) { + _values = values; + } + public ValueEval getItem(int index) { + return _values[index]; + } + public int getSize() { + return _values.length; + } + } + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + switch(args.length) { + case 3: + break; + case 2: + // complex rules to choose lookupVector and resultVector from the single area ref + throw new RuntimeException("Two arg version of LOOKUP not supported yet"); + default: + return ErrorEval.VALUE_INVALID; + } + + + try { + ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + AreaEval aeLookupVector = LookupUtils.resolveTableArrayArg(args[1]); + AreaEval aeResultVector = LookupUtils.resolveTableArrayArg(args[2]); + + ValueVector lookupVector = createVector(aeLookupVector); + ValueVector resultVector = createVector(aeResultVector); + if(lookupVector.getSize() > resultVector.getSize()) { + // Excel seems to handle this by accessing past the end of the result vector. + throw new RuntimeException("Lookup vector and result vector of differing sizes not supported yet"); + } + int index = LookupUtils.lookupIndexOfValue(lookupValue, lookupVector, true); + + return resultVector.getItem(index); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + } + + private static ValueVector createVector(AreaEval ae) { + + if(!ae.isRow() && !ae.isColumn()) { + // extra complexity required to emulate the way LOOKUP can handles these abnormal cases. + throw new RuntimeException("non-vector lookup or result areas not supported yet"); + } + return new SimpleValueVector(ae.getValues()); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java b/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java new file mode 100644 index 0000000000..d6a8489623 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/LookupUtils.java @@ -0,0 +1,530 @@ +/* ==================================================================== + 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.AreaPtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +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; + +/** + * Common functionality used by VLOOKUP, HLOOKUP, LOOKUP and MATCH + * + * @author Josh Micich + */ +final class LookupUtils { + + /** + * Represents a single row or column within an AreaEval. + */ + public interface ValueVector { + ValueEval getItem(int index); + int getSize(); + } + /** + * 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 _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; + } + if (_targetClass == StringEval.class) { + + } + 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).
    + * Sample behaviour: + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    Input   ReturnValue  Thrown Error
    54 
    2.92 
    "5"4 
    "2.18e1"21 
    "-$2"-3*
    FALSE-1*
    TRUE0 
    "TRUE" #REF!
    "abc" #REF!
    "" #REF!
    <blank> #VALUE!

    + * + * * Note - out of range errors (both too high and too low) are handled by the caller. + * @return column or row index as a zero-based value + * + */ + public static int resolveRowOrColIndexArg(ValueEval veRowColIndexArg) throws EvaluationException { + if(veRowColIndexArg == null) { + throw new IllegalArgumentException("argument must not be null"); + } + if(veRowColIndexArg instanceof BlankEval) { + throw EvaluationException.invalidValue(); + } + if(veRowColIndexArg instanceof StringEval) { + StringEval se = (StringEval) veRowColIndexArg; + String strVal = se.getStringValue(); + Double dVal = OperandResolver.parseDouble(strVal); + if(dVal == null) { + // String does not resolve to a number. Raise #VALUE! error. + throw EvaluationException.invalidRef(); + // This includes text booleans "TRUE" and "FALSE". They are not valid. + } + // else - numeric value parses OK + } + // actual BoolEval values get interpreted as FALSE->0 and TRUE->1 + return OperandResolver.coerceValueToInt(veRowColIndexArg) - 1; + } + + + + /** + * The second argument (table_array) should be an area ref, but can actually be a cell ref, in + * which case it is interpreted as a 1x1 area ref. Other scalar values cause #VALUE! error. + */ + public static AreaEval resolveTableArrayArg(Eval eval) throws EvaluationException { + if (eval instanceof AreaEval) { + return (AreaEval) eval; + } + + if(eval instanceof RefEval) { + RefEval refEval = (RefEval) eval; + // Make this cell ref look like a 1x1 area ref. + + // It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval. + // This code only requires the value array item. + // anything would be ok for rowIx and colIx, but may as well get it right. + int rowIx = refEval.getRow(); + int colIx = refEval.getColumn(); + AreaPtg ap = new AreaPtg(rowIx, rowIx, colIx, colIx, false, false, false, false); + ValueEval value = refEval.getInnerValueEval(); + return new Area2DEval(ap, new ValueEval[] { value, }); + } + throw EvaluationException.invalidValue(); + } + + + /** + * Resolves the last (optional) parameter (range_lookup) to the VLOOKUP and HLOOKUP functions. + * @param rangeLookupArg + * @param srcCellRow + * @param srcCellCol + * @return + * @throws EvaluationException + */ + public static boolean resolveRangeLookupArg(Eval rangeLookupArg, int srcCellRow, short srcCellCol) throws EvaluationException { + if(rangeLookupArg == null) { + // range_lookup arg not provided + return true; // default is TRUE + } + 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 lookup + * + * Syntax:
    + * MATCH(lookup_value, lookup_array, match_type)

    + * + * Returns a 1-based index specifying at what position in the lookup_array the specified + * lookup_value is found.

    + * + * Specific matching behaviour can be modified with the optional match_type parameter. + * + * + * + * + * + * + *
    ValueMatching Behaviour
    1(default) find the largest value that is less than or equal to lookup_value. + * The lookup_array must be in ascending order*.
    0find the first value that is exactly equal to lookup_value. + * The lookup_array can be in any order.
    -1find the smallest value that is greater than or equal to lookup_value. + * The lookup_array must be in descending order*.
    + * + * * Note regarding order - For the match_type cases that require the lookup_array to + * be ordered, MATCH() can produce incorrect results if this requirement is not met. Observed + * behaviour in Excel is to return the lowest index value for which every item after that index + * breaks the match rule.
    + * The (ascending) sort order expected by MATCH() is:
    + * numbers (low to high), strings (A to Z), boolean (FALSE to TRUE)
    + * MATCH() ignores all elements in the lookup_array with a different type to the lookup_value. + * Type conversion of the lookup_array elements is never performed. + * + * + * @author Josh Micich + */ +public final class Match implements Function { + + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + + double match_type = 1; // default + + switch(args.length) { + case 3: + try { + match_type = evaluateMatchTypeArg(args[2], srcCellRow, srcCellCol); + } catch (EvaluationException e) { + // Excel/MATCH() seems to have slightly abnormal handling of errors with + // the last parameter. Errors do not propagate up. Every error gets + // translated into #REF! + return ErrorEval.REF_INVALID; + } + case 2: + break; + default: + return ErrorEval.VALUE_INVALID; + } + + boolean matchExact = match_type == 0; + // Note - Excel does not strictly require -1 and +1 + boolean findLargestLessThanOrEqual = match_type > 0; + + + try { + ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + ValueEval[] lookupRange = evaluateLookupRange(args[1]); + int index = findIndexOfValue(lookupValue, lookupRange, matchExact, findLargestLessThanOrEqual); + return new NumberEval(index + 1); // +1 to convert to 1-based + } catch (EvaluationException e) { + return e.getErrorEval(); + } + } + + private static ValueEval[] evaluateLookupRange(Eval eval) throws EvaluationException { + if (eval instanceof RefEval) { + RefEval re = (RefEval) eval; + return new ValueEval[] { re.getInnerValueEval(), }; + } + if (eval instanceof AreaEval) { + AreaEval ae = (AreaEval) eval; + if(!ae.isColumn() && !ae.isRow()) { + throw new EvaluationException(ErrorEval.NA); + } + return ae.getValues(); + } + + // Error handling for lookup_range arg is also unusual + if(eval instanceof NumericValueEval) { + throw new EvaluationException(ErrorEval.NA); + } + if (eval instanceof StringEval) { + StringEval se = (StringEval) eval; + Double d = OperandResolver.parseDouble(se.getStringValue()); + if(d == null) { + // plain string + throw new EvaluationException(ErrorEval.VALUE_INVALID); + } + // else looks like a number + throw new EvaluationException(ErrorEval.NA); + } + throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")"); + } + + + + private static double evaluateMatchTypeArg(Eval arg, int srcCellRow, short srcCellCol) + throws EvaluationException { + Eval match_type = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); + + if(match_type instanceof ErrorEval) { + throw new EvaluationException((ErrorEval)match_type); + } + if(match_type instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) match_type; + return ne.getNumberValue(); + } + if (match_type instanceof StringEval) { + StringEval se = (StringEval) match_type; + Double d = OperandResolver.parseDouble(se.getStringValue()); + if(d == null) { + // plain string + throw new EvaluationException(ErrorEval.VALUE_INVALID); + } + // if the string parses as a number, it is OK + return d.doubleValue(); + } + throw new RuntimeException("Unexpected match_type type (" + match_type.getClass().getName() + ")"); + } + + /** + * @return zero based index + */ + private static int findIndexOfValue(ValueEval lookupValue, ValueEval[] lookupRange, + boolean matchExact, boolean findLargestLessThanOrEqual) throws EvaluationException { + + LookupValueComparer lookupComparer = createLookupComparer(lookupValue, matchExact); + + if(matchExact) { + for (int i = 0; i < lookupRange.length; i++) { + if(lookupComparer.compareTo(lookupRange[i]).isEqual()) { + return i; + } + } + throw new EvaluationException(ErrorEval.NA); + } + + if(findLargestLessThanOrEqual) { + // Note - backward iteration + for (int i = lookupRange.length - 1; i>=0; i--) { + CompareResult cmp = lookupComparer.compareTo(lookupRange[i]); + if(cmp.isTypeMismatch()) { + continue; + } + if(!cmp.isLessThan()) { + return i; + } + } + throw new EvaluationException(ErrorEval.NA); + } + + // else - find smallest greater than or equal to + // TODO - is binary search used for (match_type==+1) ? + for (int i = 0; i=0 || stringValue.indexOf('*') >=0) { + return true; + } + return false; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/MathX.java b/src/java/org/apache/poi/hssf/record/formula/functions/MathX.java new file mode 100644 index 0000000000..593998f1e9 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/MathX.java @@ -0,0 +1,565 @@ +/* +* 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 19, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + + + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * This class is an extension to the standard math library + * provided by java.lang.Math class. It follows the Math class + * in that it has a private constructor and all static methods. + */ +public final class MathX { + + + private MathX() {} + + + /** + * 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 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 0) { + product = 1; + for (int i=0, iSize=values.length; i + * When n and s are "valid" arguments, the returned value is: Math.floor(n/s) * s; + *
    + * n and s are invalid if any of following conditions are true: + *

      + *
    • s is zero
    • + *
    • n is negative and s is positive
    • + *
    • n is positive and s is negative
    • + *
    + * 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(..). + *

    + * When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s; + *
    + * n and s are invalid if any of following conditions are true: + *

      + *
    • s is zero
    • + *
    • n is negative and s is positive
    • + *
    • n is positive and s is negative
    • + *
    + * 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: + *
      + *
    • mod(3.4, 2) = 1.4
    • + *
    • mod(-3.4, 2) = 0.6
    • + *
    • mod(-3.4, -2) = -1.4
    • + *
    • mod(3.4, -2) = -0.6
    • + *
    + * 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)) { + double t = Math.abs(n / d); + t = t - (long) t; + result = sign(d) * Math.abs(t * d); + } + else { + double t = Math.abs(n / d); + t = t - (long) t; + t = Math.ceil(t) - t; + result = sign(d) * Math.abs(t * 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) { + double d2 = d*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); + d = (ePowX + ePowNegX) / 2; + return d; + } + + /** + * hyperbolic sine + * @param d + */ + public static double sinh(double d) { + double ePowX = Math.pow(Math.E, d); + double ePowNegX = Math.pow(Math.E, -d); + d = (ePowX - ePowNegX) / 2; + return d; + } + + /** + * hyperbolic tangent + * @param d + */ + public static double tanh(double d) { + double ePowX = Math.pow(Math.E, d); + double ePowNegX = Math.pow(Math.E, -d); + d = (ePowX - ePowNegX) / (ePowX + ePowNegX); + return d; + } + + /** + * returns the sum of product of corresponding double value in each + * subarray. It is the responsibility of the caller to ensure that + * all the subarrays are of equal length. If the subarrays are + * not of equal length, the return value can be unpredictable. + * @param arrays + */ + public static double sumproduct(double[][] arrays) { + double d = 0; + + try { + int narr = arrays.length; + int arrlen = arrays[0].length; + + for (int j=0; j + * It is the responsibility of the caller + * to ensure that the two subarrays are of equal length. If the + * subarrays are not of equal length, the return value can be + * unpredictable. + * @param xarr + * @param yarr + */ + public static double sumx2my2(double[] xarr, double[] yarr) { + double d = 0; + + try { + for (int i=0, iSize=xarr.length; i + * It is the responsibility of the caller + * to ensure that the two subarrays are of equal length. If the + * subarrays are not of equal length, the return value can be + * unpredictable. + * @param xarr + * @param yarr + */ + public static double sumx2py2(double[] xarr, double[] yarr) { + double d = 0; + + try { + for (int i=0, iSize=xarr.length; i + * It is the responsibility of the caller + * to ensure that the two subarrays are of equal length. If the + * subarrays are not of equal length, the return value can be + * unpredictable. + * @param xarr + * @param yarr + */ + public static double sumxmy2(double[] xarr, double[] yarr) { + double d = 0; + + try { + for (int i=0, iSize=xarr.length; i 0 ? MathX.max(values) : 0; + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java b/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java new file mode 100644 index 0000000000..e25db7b746 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Maxa.java @@ -0,0 +1,66 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public final class Maxa extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + | ValueEvalToNumericXlator.BLANK_IS_PARSED + | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + )); + + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = values.length > 0 ? MathX.max(values) : 0; + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mdeterm.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mdeterm.java new file mode 100644 index 0000000000..ab57658c6d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mdeterm.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Mdeterm extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Median.java b/src/java/org/apache/poi/hssf/record/formula/functions/Median.java new file mode 100644 index 0000000000..57a18b3314 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Median.java @@ -0,0 +1,77 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Median extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) (0 + | ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.BLANK_IS_PARSED + )); + + /** + * this is the default impl for the factory method getXlator + * of the super class NumericFunction. Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = StatsLib.median(values); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mid.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mid.java new file mode 100644 index 0000000000..7f30aa4cec --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mid.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +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; + +/** + * An implementation of the MID function
    MID returns a specific number of + * characters from a text string, starting at the specified position.

    + * + * Syntax:
    MID(text, start_num, + * num_chars)
    + * + * @author Manda Wilson < wilson at c bio dot msk cc dot org > + */ +public class Mid implements Function { + /** + * Returns a specific number of characters from a text string, starting at + * the position you specify, based on the number of characters you specify. + * + * @see org.apache.poi.hssf.record.formula.eval.Eval + */ + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + if (args.length != 3) { + return ErrorEval.VALUE_INVALID; + } + + String text; + int startIx; // zero based + int numChars; + + try { + ValueEval evText = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + text = OperandResolver.coerceValueToString(evText); + int startCharNum = evaluateNumberArg(args[1], srcCellRow, srcCellCol); + numChars = evaluateNumberArg(args[2], srcCellRow, srcCellCol); + startIx = startCharNum - 1; // convert to zero-based + } catch (EvaluationException e) { + return e.getErrorEval(); + } + + int len = text.length(); + if (startIx < 0) { + return ErrorEval.VALUE_INVALID; + } + if (numChars < 0) { + return ErrorEval.VALUE_INVALID; + } + if (numChars < 0 || startIx > len) { + return new StringEval(""); + } + int endIx = startIx + numChars; + if (endIx > len) { + endIx = len; + } + String result = text.substring(startIx, endIx); + return new StringEval(result); + + } + + private static int evaluateNumberArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException { + ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); + if (ev instanceof BlankEval) { + // Note - for start_num arg, blank causes error(#VALUE!), + // but for num_chars causes empty string to be returned. + return 0; + } + + return OperandResolver.coerceValueToInt(ev); + } +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Midb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Midb.java new file mode 100644 index 0000000000..2a06e4e09a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Midb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Midb extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Min.java b/src/java/org/apache/poi/hssf/record/formula/functions/Min.java new file mode 100644 index 0000000000..8cd896783c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Min.java @@ -0,0 +1,68 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Min extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + )); + + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = values.length > 0 ? MathX.min(values) : 0; + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java new file mode 100644 index 0000000000..21ba47b569 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mina.java @@ -0,0 +1,66 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Mina extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + | ValueEvalToNumericXlator.BLANK_IS_PARSED + )); + + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = values.length > 0 ? MathX.min(values) : 0; + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Minute.java b/src/java/org/apache/poi/hssf/record/formula/functions/Minute.java new file mode 100644 index 0000000000..a8b6836208 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Minute.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Minute extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Minverse.java b/src/java/org/apache/poi/hssf/record/formula/functions/Minverse.java new file mode 100644 index 0000000000..66f5647b7e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Minverse.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Minverse extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mirr.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mirr.java new file mode 100644 index 0000000000..c87d11307d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mirr.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Mirr extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mmult.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mmult.java new file mode 100644 index 0000000000..95a4bf2f70 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mmult.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Mmult extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mod.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mod.java new file mode 100644 index 0000000000..ebef231544 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mod.java @@ -0,0 +1,87 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Mod extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d0 = 0; + double d1 = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d0 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + if (retval == null) { + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d1 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + if (d1 == 0) { + retval = ErrorEval.DIV_ZERO; + } + else { + double d = MathX.mod(d0, d1); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java b/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java new file mode 100644 index 0000000000..724b6e6543 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Mode.java @@ -0,0 +1,78 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Mode extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) (0 + //| ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.BLANK_IS_PARSED + )); + + /** + * this is the default impl for the factory method getXlator + * of the super class NumericFunction. Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = StatsLib.mode(values); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Month.java b/src/java/org/apache/poi/hssf/record/formula/functions/Month.java new file mode 100644 index 0000000000..d5178b22df --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Month.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; + +/** + * + * @author Guenter Kickinger g.kickinger@gmx.net + * + */ +public class Month extends NumericFunction { + + /* (non-Javadoc) + * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) + */ + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { + java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem + retval = new NumberEval(d.getMonth()+1); + } else { + retval = ErrorEval.NUM_ERROR; + } + } + else if (ve instanceof BlankEval) { + // do nothing + } else { + retval = ErrorEval.NUM_ERROR; + } + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java new file mode 100644 index 0000000000..0e7cce217e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java @@ -0,0 +1,202 @@ +/* +* 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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.Ref2DEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * This is the super class for all excel function evaluator + * classes that take variable number of operands, and + * where the order of operands does not matter + */ +public abstract class MultiOperandNumericFunction extends NumericFunction { + static final double[] EMPTY_DOUBLE_ARRAY = { }; + + private static class DoubleList { + private double[] _array; + private int _count; + + public DoubleList() { + _array = new double[8]; + _count = 0; + } + + public double[] toArray() { + if(_count < 1) { + return EMPTY_DOUBLE_ARRAY; + } + double[] result = new double[_count]; + System.arraycopy(_array, 0, result, 0, _count); + return result; + } + + public void add(double[] values) { + int addLen = values.length; + ensureCapacity(_count + addLen); + System.arraycopy(values, 0, _array, _count, addLen); + _count += addLen; + } + + private void ensureCapacity(int reqSize) { + if(reqSize > _array.length) { + int newSize = reqSize * 3 / 2; // grow with 50% extra + double[] newArr = new double[newSize]; + System.arraycopy(_array, 0, newArr, 0, _count); + _array = newArr; + } + } + + public void add(double value) { + ensureCapacity(_count + 1); + _array[_count] = value; + _count++; + } + } + + private static final int DEFAULT_MAX_NUM_OPERANDS = 30; + + protected abstract ValueEvalToNumericXlator getXlator(); + + /** + * Maximum number of operands accepted by this function. + * Subclasses may override to change default value. + */ + protected int getMaxNumOperands() { + return DEFAULT_MAX_NUM_OPERANDS; + } + + /** + * Returns a double array that contains values for the numeric cells + * from among the list of operands. Blanks and Blank equivalent cells + * are ignored. Error operands or cells containing operands of type + * that are considered invalid and would result in #VALUE! error in + * excel cause this function to return null. + * + * @param operands + * @param srcRow + * @param srcCol + */ + protected double[] getNumberArray(Eval[] operands, int srcRow, short srcCol) { + if (operands.length > getMaxNumOperands()) { + return null; + } + DoubleList retval = new DoubleList(); + + for (int i=0, iSize=operands.length; ifalse if any sub-array is missing, or is of different length + */ + protected static final boolean areSubArraysConsistent(double[][] values) { + + if (values == null || values.length < 1) { + // TODO this doesn't seem right. Fix or add comment. + return true; + } + + if (values[0] == null) { + return false; + } + int outerMax = values.length; + int innerMax = values[0].length; + for (int i=1; i 'number is non-zero' + */ +public class Not extends BooleanFunction { + + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + boolean b = true; + ValueEval tempVe = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + if (operands[0] instanceof AreaEval) { + AreaEval ae = (AreaEval) operands[0]; + if (ae.isRow() && ae.containsColumn(srcCol)) { + ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); + tempVe = singleOperandEvaluate(ve); + } else if (ae.isColumn() && ae.containsRow(srcRow)) { + ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); + tempVe = singleOperandEvaluate(ve); + } else { + retval = ErrorEval.VALUE_INVALID; + } + } + else { + tempVe = singleOperandEvaluate(operands[0]); + if (tempVe instanceof StringEval) { + retval = ErrorEval.VALUE_INVALID; + } + else if (tempVe instanceof ErrorEval) { + retval = tempVe; + } + } + } + + if (retval == null) { // if no error + if (tempVe instanceof BoolEval) { + b = b && ((BoolEval) tempVe).getBooleanValue(); + } + else if (tempVe instanceof StringEval) { + retval = ErrorEval.VALUE_INVALID; + } + else if (tempVe instanceof ErrorEval) { + retval = tempVe; + } + retval = b ? BoolEval.FALSE : BoolEval.TRUE; + } + + return retval; + } + + + protected ValueEval singleOperandEvaluate(Eval ve) { + ValueEval retval = ErrorEval.VALUE_INVALID; + if (ve instanceof RefEval) { + RefEval re = (RefEval) ve; + retval = singleOperandEvaluate(re.getInnerValueEval()); + } + else if (ve instanceof BoolEval) { + retval = (BoolEval) ve; + } + else if (ve instanceof NumberEval) { + NumberEval ne = (NumberEval) ve; + retval = ne.getNumberValue() != 0 ? BoolEval.TRUE : BoolEval.FALSE; + } + else if (ve instanceof StringEval) { + StringEval se = (StringEval) ve; + String str = se.getStringValue(); + retval = str.equalsIgnoreCase("true") + ? BoolEval.TRUE + : str.equalsIgnoreCase("false") + ? BoolEval.FALSE + : (ValueEval) ErrorEval.VALUE_INVALID; + } + else if (ve instanceof BlankEval) { + retval = BoolEval.FALSE; + } + else { + retval = ErrorEval.VALUE_INVALID; + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java new file mode 100644 index 0000000000..49ed84fb46 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java @@ -0,0 +1,41 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; + +/** + * + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * This is the default implementation of a Function class. + * The default behaviour is to return a non-standard ErrorEval + * "ErrorEval.FUNCTION_NOT_IMPLEMENTED". This error should alert + * the user that the formula contained a function that is not + * yet implemented. + */ +public class NotImplementedFunction implements Function { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + return ErrorEval.FUNCTION_NOT_IMPLEMENTED; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Note.java b/src/java/org/apache/poi/hssf/record/formula/functions/Note.java new file mode 100644 index 0000000000..210770ad71 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Note.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Note extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Now.java b/src/java/org/apache/poi/hssf/record/formula/functions/Now.java new file mode 100644 index 0000000000..2c23a97b37 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Now.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Now extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Nper.java b/src/java/org/apache/poi/hssf/record/formula/functions/Nper.java new file mode 100644 index 0000000000..95411edb77 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Nper.java @@ -0,0 +1,75 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Nper extends FinanceFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double rate = 0, fv = 0, pmt = 0, pv = 0, d = 0; + boolean type = false; + ValueEval retval = null; + ValueEval ve = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 5: + ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol); + if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; } + type = ((BoolEval) ve).getBooleanValue(); + case 4: + ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + + ve = singleOperandEvaluate(operands[2], srcRow, srcCol); + if (ve instanceof NumericValueEval) pv = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + + ve = singleOperandEvaluate(operands[3], srcRow, srcCol); + if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + } + + if (retval == null) { + d = FinanceLib.nper(rate, pmt, pv, fv, type); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : (Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Npv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Npv.java new file mode 100644 index 0000000000..9e57999d76 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Npv.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Npv extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Numberstring.java b/src/java/org/apache/poi/hssf/record/formula/functions/Numberstring.java new file mode 100644 index 0000000000..51403415cd --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Numberstring.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Numberstring extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/NumericFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/NumericFunction.java new file mode 100644 index 0000000000..fd96f1495a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/NumericFunction.java @@ -0,0 +1,98 @@ +/* +* 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 14, 2005 + * + */ +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.Eval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class NumericFunction implements Function { + + protected static final double E = Math.E; + protected static final double PI = Math.PI; + + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + | ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + )); + + private static final int DEFAULT_MAX_NUM_OPERANDS = 30; + + /** + * this is the default impl of the factory(ish) method getXlator. + * Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { + ValueEval retval; + if (eval instanceof AreaEval) { + AreaEval ae = (AreaEval) eval; + if (ae.contains(srcRow, srcCol)) { // circular ref! + retval = ErrorEval.CIRCULAR_REF_ERROR; + } + else if (ae.isRow()) { + if (ae.containsColumn(srcCol)) { + ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); + ve = getXlator().attemptXlateToNumeric(ve); + retval = getXlator().attemptXlateToNumeric(ve); + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else if (ae.isColumn()) { + if (ae.containsRow(srcRow)) { + ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); + retval = getXlator().attemptXlateToNumeric(ve); + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else { + retval = getXlator().attemptXlateToNumeric((ValueEval) eval); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Odd.java b/src/java/org/apache/poi/hssf/record/formula/functions/Odd.java new file mode 100644 index 0000000000..8af68c3db5 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Odd.java @@ -0,0 +1,73 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Odd extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + if (!Double.isNaN(d) && !Double.isInfinite(d)) { + d = (d==0) + ? 1 + : ((((long) d) - 1) % 2 == 0) + ? d + : (d < 0) + ? ((((long) (d/2))<<1)-1) + : ((((long) (d/2))<<1)+1); + } + retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Offset.java b/src/java/org/apache/poi/hssf/record/formula/functions/Offset.java new file mode 100644 index 0000000000..9497a5f21a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Offset.java @@ -0,0 +1,362 @@ +/* +* 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.Area3DPtg; +import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.hssf.record.formula.eval.Area3DEval; +import org.apache.poi.hssf.record.formula.eval.AreaEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.Ref3DEval; +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; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +/** + * Implementation for Excel function OFFSET()

    + * + * OFFSET returns an area reference that is a specified number of rows and columns from a + * reference cell or area.

    + * + * Syntax:
    + * 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 FreeRefFunction { + // These values are specific to BIFF8 + private static final int LAST_VALID_ROW_INDEX = 0xFFFF; + private static final int LAST_VALID_COLUMN_INDEX = 0xFF; + + + /** + * Exceptions are used within this class to help simplify flow control when error conditions + * are encountered + */ + private static final class EvalEx extends Exception { + private final ErrorEval _error; + + public EvalEx(ErrorEval error) { + _error = error; + } + public ErrorEval getError() { + return _error; + } + } + + /** + * 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 static final int INVALID_SHEET_INDEX = -1; + private final int _firstRowIndex; + private final int _firstColumnIndex; + private final int _width; + private final int _height; + private final int _externalSheetIndex; + + public BaseRef(RefEval re) { + _firstRowIndex = re.getRow(); + _firstColumnIndex = re.getColumn(); + _height = 1; + _width = 1; + if (re instanceof Ref3DEval) { + Ref3DEval r3e = (Ref3DEval) re; + _externalSheetIndex = r3e.getExternSheetIndex(); + } else { + _externalSheetIndex = INVALID_SHEET_INDEX; + } + } + + public BaseRef(AreaEval ae) { + _firstRowIndex = ae.getFirstRow(); + _firstColumnIndex = ae.getFirstColumn(); + _height = ae.getLastRow() - ae.getFirstRow() + 1; + _width = ae.getLastColumn() - ae.getFirstColumn() + 1; + if (ae instanceof Area3DEval) { + Area3DEval a3e = (Area3DEval) ae; + _externalSheetIndex = a3e.getExternSheetIndex(); + } else { + _externalSheetIndex = INVALID_SHEET_INDEX; + } + } + + public int getWidth() { + return _width; + } + + public int getHeight() { + return _height; + } + + public int getFirstRowIndex() { + return _firstRowIndex; + } + + public int getFirstColumnIndex() { + return _firstColumnIndex; + } + + public boolean isIs3d() { + return _externalSheetIndex > 0; + } + + public short getExternalSheetIndex() { + if(_externalSheetIndex < 0) { + throw new IllegalStateException("external sheet index only available for 3d refs"); + } + return (short) _externalSheetIndex; + } + + } + + public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { + + 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, workbook, sheet); + } catch (EvalEx e) { + return e.getError(); + } + } + + + private static AreaEval createOffset(BaseRef baseRef, + LinearOffsetRange rowOffsetRange, LinearOffsetRange colOffsetRange, + HSSFWorkbook workbook, HSSFSheet sheet) throws EvalEx { + + LinearOffsetRange rows = rowOffsetRange.normaliseAndTranslate(baseRef.getFirstRowIndex()); + LinearOffsetRange cols = colOffsetRange.normaliseAndTranslate(baseRef.getFirstColumnIndex()); + + if(rows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) { + throw new EvalEx(ErrorEval.REF_INVALID); + } + if(cols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) { + throw new EvalEx(ErrorEval.REF_INVALID); + } + if(baseRef.isIs3d()) { + Area3DPtg a3dp = new Area3DPtg(rows.getFirstIndex(), rows.getLastIndex(), + cols.getFirstIndex(), cols.getLastIndex(), + false, false, false, false, + baseRef.getExternalSheetIndex()); + return HSSFFormulaEvaluator.evaluateArea3dPtg(workbook, a3dp); + } + + AreaPtg ap = new AreaPtg(rows.getFirstIndex(), rows.getLastIndex(), + cols.getFirstIndex(), cols.getLastIndex(), + false, false, false, false); + return HSSFFormulaEvaluator.evaluateAreaPtg(sheet, workbook, ap); + } + + + private static BaseRef evaluateBaseRef(Eval eval) throws EvalEx { + + if(eval instanceof RefEval) { + return new BaseRef((RefEval)eval); + } + if(eval instanceof AreaEval) { + return new BaseRef((AreaEval)eval); + } + if (eval instanceof ErrorEval) { + throw new EvalEx((ErrorEval) eval); + } + throw new EvalEx(ErrorEval.VALUE_INVALID); + } + + + /** + * OFFSET's numeric arguments (2..5) have similar processing rules + */ + private static int evaluateIntArg(Eval eval, int srcCellRow, short srcCellCol) throws EvalEx { + + double d = evaluateDoubleArg(eval, srcCellRow, srcCellCol); + return convertDoubleToInt(d); + } + + /** + * Fractional values are silently truncated by Excel. + * Truncation is toward negative infinity. + */ + /* package */ static int convertDoubleToInt(double d) { + // 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); + } + + + private static double evaluateDoubleArg(Eval eval, int srcCellRow, short srcCellCol) throws EvalEx { + ValueEval ve = evaluateSingleValue(eval, srcCellRow, srcCellCol); + + if (ve instanceof NumericValueEval) { + return ((NumericValueEval) ve).getNumberValue(); + } + if (ve instanceof StringEval) { + StringEval se = (StringEval) ve; + Double d = parseDouble(se.getStringValue()); + if(d == null) { + throw new EvalEx(ErrorEval.VALUE_INVALID); + } + return d.doubleValue(); + } + if (ve instanceof BoolEval) { + // in the context of OFFSET, booleans resolve to 0 and 1. + if(((BoolEval) ve).getBooleanValue()) { + return 1; + } + return 0; + } + throw new RuntimeException("Unexpected eval type (" + ve.getClass().getName() + ")"); + } + + private static Double parseDouble(String s) { + // TODO - find a home for this method + // TODO - support various number formats: sign char, dollars, commas + // OFFSET and COUNTIF seem to handle these + return Countif.parseDouble(s); + } + + private static ValueEval evaluateSingleValue(Eval eval, int srcCellRow, short srcCellCol) throws EvalEx { + if(eval instanceof RefEval) { + return ((RefEval)eval).getInnerValueEval(); + } + if(eval instanceof AreaEval) { + return chooseSingleElementFromArea((AreaEval)eval, srcCellRow, srcCellCol); + } + if (eval instanceof ValueEval) { + return (ValueEval) eval; + } + throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")"); + } + + // TODO - this code seems to get repeated a bit + private static ValueEval chooseSingleElementFromArea(AreaEval ae, int srcCellRow, short srcCellCol) throws EvalEx { + if (ae.isColumn()) { + if (ae.isRow()) { + return ae.getValues()[0]; + } + if (!ae.containsRow(srcCellRow)) { + throw new EvalEx(ErrorEval.VALUE_INVALID); + } + return ae.getValueAt(srcCellRow, ae.getFirstColumn()); + } + if (!ae.isRow()) { + throw new EvalEx(ErrorEval.VALUE_INVALID); + } + if (!ae.containsColumn(srcCellCol)) { + throw new EvalEx(ErrorEval.VALUE_INVALID); + } + return ae.getValueAt(ae.getFirstRow(), srcCellCol); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Or.java b/src/java/org/apache/poi/hssf/record/formula/functions/Or.java new file mode 100644 index 0000000000..22d7003d4d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Or.java @@ -0,0 +1,81 @@ +/* +* 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 9, 2005 + * + */ +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.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Or extends BooleanFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval = null; + boolean b = false; + boolean atleastOneNonBlank = false; + + /* + * Note: do not abort the loop if b is true, since we could be + * dealing with errorevals later. + */ + outer: + for (int i=0, iSize=operands.length; i + * + * Syntax:
    + * PMT(rate, nper, pv, fv, type)

    + * + * Returns the constant repayment amount required for a loan assuming a constant interest rate.

    + * + * rate the loan interest rate.
    + * nper the number of loan repayments.
    + * pv the present value of the future payments (or principle).
    + * fv the future value (default zero) surplus cash at the end of the loan lifetime.
    + * type whether payments are due at the beginning(1) or end(0 - default) of each payment period.
    + * + */ +public final class Pmt extends FinanceFunction { + + public Eval evaluate(Eval[] args, int srcRow, short srcCol) { + + if(args.length < 3 || args.length > 5) { + return ErrorEval.VALUE_INVALID; + } + + try { + // evaluate first three (always present) args + double rate = evalArg(args[0], srcRow, srcCol); + double nper = evalArg(args[1], srcRow, srcCol); + double pv = evalArg(args[2], srcRow, srcCol); + double fv = 0; + boolean arePaymentsAtPeriodBeginning = false; + + switch (args.length) { + case 5: + ValueEval ve = singleOperandNumericAsBoolean(args[4], srcRow, srcCol); + if (ve instanceof ErrorEval) { + return ve; + } + arePaymentsAtPeriodBeginning = ((BoolEval) ve).getBooleanValue(); + case 4: + fv = evalArg(args[3], srcRow, srcCol); + } + double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning); + if (Double.isNaN(d)) { + return (ValueEval) ErrorEval.VALUE_INVALID; + } + if (Double.isInfinite(d)) { + return (ValueEval) ErrorEval.NUM_ERROR; + } + return new NumberEval(d); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + } + + private double evalArg(Eval arg, int srcRow, short srcCol) throws EvaluationException { + ValueEval ve = singleOperandEvaluate(arg, srcRow, srcCol); + if(ve instanceof ErrorEval) { + throw new EvaluationException((ErrorEval) ve); + } + if (ve instanceof NumericValueEval) { + return ((NumericValueEval) ve).getNumberValue(); + } + throw new EvaluationException(ErrorEval.VALUE_INVALID); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Poisson.java b/src/java/org/apache/poi/hssf/record/formula/functions/Poisson.java new file mode 100644 index 0000000000..f4aba4c7f1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Poisson.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Poisson extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Power.java b/src/java/org/apache/poi/hssf/record/formula/functions/Power.java new file mode 100644 index 0000000000..1327e80061 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Power.java @@ -0,0 +1,80 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Power extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d0 = 0; + double d1 = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d0 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + if (retval == null) { + ValueEval vev = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (vev instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) vev; + d1 = ne.getNumberValue(); + } + else if (vev instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + double d = Math.pow(d0, d1); + retval = (Double.isNaN(d) || Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ppmt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ppmt.java new file mode 100644 index 0000000000..4e36630b94 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ppmt.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Ppmt extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Prob.java b/src/java/org/apache/poi/hssf/record/formula/functions/Prob.java new file mode 100644 index 0000000000..12293687f1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Prob.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Prob extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Product.java b/src/java/org/apache/poi/hssf/record/formula/functions/Product.java new file mode 100644 index 0000000000..a88a3245d6 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Product.java @@ -0,0 +1,68 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Product extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + )); + + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = MathX.product(values); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Proper.java b/src/java/org/apache/poi/hssf/record/formula/functions/Proper.java new file mode 100644 index 0000000000..26a8c3a90a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Proper.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Proper extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Pv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Pv.java new file mode 100644 index 0000000000..1d54bee93d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Pv.java @@ -0,0 +1,74 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +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.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Pv extends FinanceFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double rate = 0, fv = 0, nper = 0, pmt = 0, d = 0; + boolean type = false; + ValueEval retval = null; + ValueEval ve = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 5: + ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol); + if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; } + type = ((BoolEval) ve).getBooleanValue(); + case 4: + ve = singleOperandEvaluate(operands[3], srcRow, srcCol); + if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + case 3: + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) nper = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + + ve = singleOperandEvaluate(operands[2], srcRow, srcCol); + if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + + ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue(); + else { retval = ErrorEval.VALUE_INVALID; break; } + } + + if (retval == null) { + d = FinanceLib.pv(rate, nper, pmt, fv, type); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : (Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Quartile.java b/src/java/org/apache/poi/hssf/record/formula/functions/Quartile.java new file mode 100644 index 0000000000..ec81094f1f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Quartile.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Quartile extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Radians.java b/src/java/org/apache/poi/hssf/record/formula/functions/Radians.java new file mode 100644 index 0000000000..836fab3ad1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Radians.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Radians extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.toRadians(d); + retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rand.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rand.java new file mode 100644 index 0000000000..4c180383d8 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rand.java @@ -0,0 +1,46 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Rand implements Function { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval; + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 0: + retval = new NumberEval(Math.random()); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rank.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rank.java new file mode 100644 index 0000000000..2bb13d3fec --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rank.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Rank extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rate.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rate.java new file mode 100644 index 0000000000..485920c751 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rate.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Rate extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Reftext.java b/src/java/org/apache/poi/hssf/record/formula/functions/Reftext.java new file mode 100644 index 0000000000..3ba7bc988a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Reftext.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Reftext extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Relref.java b/src/java/org/apache/poi/hssf/record/formula/functions/Relref.java new file mode 100644 index 0000000000..7e7bee8df8 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Relref.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Relref extends NotImplementedFunction { + +} 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 new file mode 100644 index 0000000000..95413f0823 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Replace.java @@ -0,0 +1,112 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.StringValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * An implementation of the REPLACE function: + * Replaces part of a text string based on the number of characters + * you specify, with another text string. + * @author Manda Wilson < wilson at c bio dot msk cc dot org > + */ +public class Replace extends TextFunction { + + /** + * Replaces part of a text string based on the number of characters + * you specify, with another text string. + * + * @see org.apache.poi.hssf.record.formula.eval.Eval + */ + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = null; + String oldStr = null; + String newStr = null; + int startNum = 0; + int numChars = 0; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + case 4: + // first operand is text string containing characters to replace + // second operand is position of first character to replace + // third operand is the number of characters in the old string + // you want to replace with new string + // fourth operand is the new string + ValueEval firstveval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + ValueEval secondveval = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); + ValueEval thirdveval = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol); + ValueEval fourthveval = singleOperandEvaluate(operands[3], srcCellRow, srcCellCol); + if (firstveval instanceof StringValueEval + && secondveval instanceof NumericValueEval + && thirdveval instanceof NumericValueEval + && fourthveval instanceof StringValueEval) { + + StringValueEval oldStrEval = (StringValueEval) firstveval; + oldStr = oldStrEval.getStringValue(); + + NumericValueEval startNumEval = (NumericValueEval) secondveval; + // NOTE: it is safe to cast to int here + // because in Excel =REPLACE("task", 2.7, 3, "est") + // returns test + // so 2.7 must be truncated to 2 + // and =REPLACE("task", 1, 1.9, "") returns ask + // so 1.9 must be truncated to 1 + startNum = (int) startNumEval.getNumberValue(); + + NumericValueEval numCharsEval = (NumericValueEval) thirdveval; + numChars = (int) numCharsEval.getNumberValue(); + + StringValueEval newStrEval = (StringValueEval) fourthveval; + newStr = newStrEval.getStringValue(); + } else { + retval = ErrorEval.VALUE_INVALID; + } + } + + if (retval == null) { + if (startNum < 1 || numChars < 0) { + retval = ErrorEval.VALUE_INVALID; + } else { + 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); + } + retval = new StringEval(strBuff.toString()); + } + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Replaceb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Replaceb.java new file mode 100644 index 0000000000..93d05bf083 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Replaceb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Replaceb extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rept.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rept.java new file mode 100644 index 0000000000..ce56e70d9d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rept.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Rept extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Request.java b/src/java/org/apache/poi/hssf/record/formula/functions/Request.java new file mode 100644 index 0000000000..23eeea5ce0 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Request.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Request extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Result.java b/src/java/org/apache/poi/hssf/record/formula/functions/Result.java new file mode 100644 index 0000000000..c15f2421e1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Result.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Result extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Right.java b/src/java/org/apache/poi/hssf/record/formula/functions/Right.java new file mode 100644 index 0000000000..771d045734 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Right.java @@ -0,0 +1,108 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.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 > + * + */ +public class Right extends TextFunction { + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = ErrorEval.VALUE_INVALID; + int index = 1; + switch (operands.length) { + default: + break; + case 2: + Eval indexEval = operands[1]; + index = evaluateAsInteger(indexEval); + if (index < 0) { + break; + } + case 1: + ValueEval veval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + String str = null; + if (veval instanceof StringEval) { + StringEval stringEval = (StringEval) veval; + str = stringEval.getStringValue(); + } + else if (veval instanceof BoolEval) { + BoolEval beval = (BoolEval) veval; + str = beval.getBooleanValue() ? "TRUE" : "FALSE"; + } + else if (veval instanceof NumberEval) { + NumberEval neval = (NumberEval) veval; + str = neval.getStringValue(); + } + if (null != str) { + int strlen = str.length(); + str = str.substring(Math.max(0, strlen-index)); + retval = new StringEval(str); + } + } + return retval; + } + + protected int evaluateAsInteger(Eval eval) { + int numval = -1; + if (eval instanceof NumberEval) { + NumberEval neval = (NumberEval) eval; + double d = neval.getNumberValue(); + numval = (int) d; + } + else if (eval instanceof StringEval) { + StringEval seval = (StringEval) eval; + String s = seval.getStringValue(); + try { + double d = Double.parseDouble(s); + numval = (int) d; + } + catch (Exception e) { + } + } + else if (eval instanceof BoolEval) { + BoolEval beval = (BoolEval) eval; + numval = beval.getBooleanValue() ? 1 : 0; + } + else if (eval instanceof RefEval) { + numval = evaluateAsInteger(xlateRefEval((RefEval) eval)); + } + return numval; + } + + protected Eval xlateRefEval(RefEval reval) { + Eval retval = reval.getInnerValueEval(); + + if (retval instanceof RefEval) { + retval = xlateRefEval((RefEval) retval); + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rightb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rightb.java new file mode 100644 index 0000000000..4ee99fdf04 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rightb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Rightb extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Roman.java b/src/java/org/apache/poi/hssf/record/formula/functions/Roman.java new file mode 100644 index 0000000000..c2db7e86c6 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Roman.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Roman extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Round.java b/src/java/org/apache/poi/hssf/record/formula/functions/Round.java new file mode 100644 index 0000000000..db4f1db0ee --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Round.java @@ -0,0 +1,83 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Round extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d0 = 0; + double d1 = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d0 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + if (retval == null) { + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d1 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + double d; + if (d0 > Integer.MAX_VALUE) { + d = (Double.isNaN(d0) || Double.isInfinite(d0)) + ? Double.NaN + : 0; + } + else { + d = MathX.round(d0, (int) d1); + } + retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Rounddown.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rounddown.java new file mode 100644 index 0000000000..13522294fd --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rounddown.java @@ -0,0 +1,86 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Rounddown extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d0 = 0; + double d1 = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if(ve instanceof ErrorEval) { + return ve; + } + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d0 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + if (retval == null) { + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d1 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + double d; + if (d0 > Integer.MAX_VALUE) { + d = (Double.isInfinite(d0)) + ? Double.NaN + : 0; + } + else { + d = MathX.roundDown(d0, (int) d1); + } + retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Roundup.java b/src/java/org/apache/poi/hssf/record/formula/functions/Roundup.java new file mode 100644 index 0000000000..4dae76d981 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Roundup.java @@ -0,0 +1,88 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Roundup extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d0 = 0; + double d1 = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 2: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if(ve instanceof ErrorEval) { + return ve; + } + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d0 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + + if (retval == null) { + ve = singleOperandEvaluate(operands[1], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d1 = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + } + + if (retval == null) { + double d; + if (d0 > Integer.MAX_VALUE) { + d = (Double.isNaN(d0)) + ? Double.NaN + : 0; + } + else { + d = MathX.roundUp(d0, (int) d1); + } + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Row.java b/src/java/org/apache/poi/hssf/record/formula/functions/Row.java new file mode 100644 index 0000000000..d111d594b5 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Row.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.AreaEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Row implements Function { + + public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + int rnum = -1; + + switch (evals.length) { + default: + retval = ErrorEval.VALUE_INVALID; + case 1: + if (evals[0] instanceof AreaEval) { + AreaEval ae = (AreaEval) evals[0]; + rnum = ae.getFirstRow(); + } + else if (evals[0] instanceof RefEval) { + RefEval re = (RefEval) evals[0]; + rnum = re.getRow(); + } + else { // anything else is not valid argument + retval = ErrorEval.VALUE_INVALID; + } + break; + case 0: + rnum = srcCellRow; + } + + if (retval == null) { + retval = (rnum >= 0) + ? new NumberEval(rnum + 1) // +1 since excel rownums are 1 based + : (ValueEval) ErrorEval.VALUE_INVALID; + } + + return retval; + } + +} 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 new file mode 100644 index 0000000000..aabffab2f6 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rows.java @@ -0,0 +1,59 @@ +/* +* 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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; + +/** + * Implementation for Excel ROWS function. + * + * @author Josh Micich + */ +public final class Rows implements Function { + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + switch(args.length) { + case 1: + // expected + break; + case 0: + // too few arguments + return ErrorEval.VALUE_INVALID; + default: + // too many arguments + return ErrorEval.VALUE_INVALID; + } + Eval firstArg = args[0]; + + int result; + if (firstArg instanceof AreaEval) { + AreaEval ae = (AreaEval) firstArg; + result = ae.getLastRow() - ae.getFirstRow() + 1; + } else if (firstArg 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/Rsq.java b/src/java/org/apache/poi/hssf/record/formula/functions/Rsq.java new file mode 100644 index 0000000000..f1addc391f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Rsq.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Rsq extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Search.java b/src/java/org/apache/poi/hssf/record/formula/functions/Search.java new file mode 100644 index 0000000000..351495c6ce --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Search.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Search extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Searchb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Searchb.java new file mode 100644 index 0000000000..3dfa711ab6 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Searchb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Searchb extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Second.java b/src/java/org/apache/poi/hssf/record/formula/functions/Second.java new file mode 100644 index 0000000000..3ebd5534a7 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Second.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Second extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Series.java b/src/java/org/apache/poi/hssf/record/formula/functions/Series.java new file mode 100644 index 0000000000..3e60685936 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Series.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Series extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Setname.java b/src/java/org/apache/poi/hssf/record/formula/functions/Setname.java new file mode 100644 index 0000000000..5f01782027 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Setname.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Setname extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Setvalue.java b/src/java/org/apache/poi/hssf/record/formula/functions/Setvalue.java new file mode 100644 index 0000000000..c86e65e80c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Setvalue.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Setvalue extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sign.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sign.java new file mode 100644 index 0000000000..2353cf47f9 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sign.java @@ -0,0 +1,62 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +public class Sign extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : new NumberEval(MathX.sign(d)); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sin.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sin.java new file mode 100644 index 0000000000..1e7669302e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sin.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Sin extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.sin(d); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java new file mode 100644 index 0000000000..8b03502865 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sinh.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Sinh extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = MathX.sinh(d); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Skew.java b/src/java/org/apache/poi/hssf/record/formula/functions/Skew.java new file mode 100644 index 0000000000..bb6d259fb0 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Skew.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Skew extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sln.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sln.java new file mode 100644 index 0000000000..dfb81768c4 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sln.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Sln extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Slope.java b/src/java/org/apache/poi/hssf/record/formula/functions/Slope.java new file mode 100644 index 0000000000..fb631f5649 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Slope.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Slope extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Small.java b/src/java/org/apache/poi/hssf/record/formula/functions/Small.java new file mode 100644 index 0000000000..9fcdc1045e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Small.java @@ -0,0 +1,81 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Small extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) (0 + | ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.BLANK_IS_PARSED + )); + + /** + * this is the default impl for the factory method getXlator + * of the super class NumericFunction. Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] ops = getNumberArray(operands, srcCellRow, srcCellCol); + if (ops == null || ops.length < 2) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double[] values = new double[ops.length-1]; + int k = (int) ops[ops.length-1]; + System.arraycopy(ops, 0, values, 0, values.length); + double d = StatsLib.kthSmallest(values, k); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java new file mode 100644 index 0000000000..57ce5cf48d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sqrt.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Sqrt extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.sqrt(d); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Standardize.java b/src/java/org/apache/poi/hssf/record/formula/functions/Standardize.java new file mode 100644 index 0000000000..6fa1df51cf --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Standardize.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Standardize extends NotImplementedFunction { + +} 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 new file mode 100644 index 0000000000..8ebccfd950 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/StatsLib.java @@ -0,0 +1,170 @@ +/* +* 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 30, 2005 + * + */ +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 + */ +public final class StatsLib { + + private StatsLib() {} + + + /** + * 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 1) { + r = Math.sqrt( devsq(v) / (v.length - 1) ); + } + return r; + } + + /** + * if v is zero length or contains no duplicates, return value + * is Double.NaN. Else returns the value that occurs most times + * and if there is a tie, returns the first such value. + * @param v + */ + public static double mode(double[] v) { + double r = Double.NaN; + + // very naive impl, may need to be optimized + if (v!=null && v.length > 1) { + int[] counts = new int[v.length]; + Arrays.fill(counts, 1); + for (int i=0, iSize=v.length; i maxc) { + maxv = v[i]; + maxc = counts[i]; + } + } + r = (maxc > 1) ? maxv : Double.NaN; // "no-dups" check + } + return r; + } + + public static double median(double[] v) { + double r = Double.NaN; + + if (v!=null && v.length >= 1) { + int n = v.length; + Arrays.sort(v); + r = (n % 2 == 0) + ? (v[n / 2] + v[n / 2 - 1]) / 2 + : v[n / 2]; + } + + return r; + } + + + public static double devsq(double[] v) { + double r = Double.NaN; + if (v!=null && v.length >= 1) { + double m = 0; + double s = 0; + int n = v.length; + for (int i=0; i + * k <= 0 & k >= v.length and null or empty arrays + * will result in return value Double.NaN + * @param v + * @param k + */ + public static double kthLargest(double[] v, int k) { + double r = Double.NaN; + k--; // since arrays are 0-based + if (v!=null && v.length > k && k >= 0) { + Arrays.sort(v); + r = v[v.length-k-1]; + } + return r; + } + + /** + * returns the kth smallest element in the array. Duplicates + * are considered as distinct values. Hence, eg. + * for array {1,1,2,4,3,3} & k=2, returned value is 1. + *
    + * 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; + k--; // since arrays are 0-based + if (v!=null && v.length > k && k >= 0) { + Arrays.sort(v); + r = v[k]; + } + return r; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Stdev.java b/src/java/org/apache/poi/hssf/record/formula/functions/Stdev.java new file mode 100644 index 0000000000..7995e66c34 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Stdev.java @@ -0,0 +1,76 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Stdev extends MultiOperandNumericFunction { + + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + )); + + /** + * this is the default impl for the factory method getXlator + * of the super class NumericFunction. Subclasses can override this method + * if they desire to return a different ValueEvalToNumericXlator instance + * than the default. + */ + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = StatsLib.stdev(values); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Stdeva.java b/src/java/org/apache/poi/hssf/record/formula/functions/Stdeva.java new file mode 100644 index 0000000000..50306a2d69 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Stdeva.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Stdeva extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Stdevp.java b/src/java/org/apache/poi/hssf/record/formula/functions/Stdevp.java new file mode 100644 index 0000000000..c270c3c7f9 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Stdevp.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Stdevp extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Stdevpa.java b/src/java/org/apache/poi/hssf/record/formula/functions/Stdevpa.java new file mode 100644 index 0000000000..2554b22014 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Stdevpa.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Stdevpa extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Step.java b/src/java/org/apache/poi/hssf/record/formula/functions/Step.java new file mode 100644 index 0000000000..3febcca471 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Step.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Step extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Steyx.java b/src/java/org/apache/poi/hssf/record/formula/functions/Steyx.java new file mode 100644 index 0000000000..d92f3ef405 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Steyx.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Steyx extends NotImplementedFunction { + +} 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 new file mode 100644 index 0000000000..9d2e9ce361 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Substitute.java @@ -0,0 +1,117 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.StringValueEval; +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 class Substitute extends TextFunction { + private static final int REPLACE_ALL = -1; + + /** + *Substitutes text in a text string with new text, some number of times. + * + * @see org.apache.poi.hssf.record.formula.eval.Eval + */ + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + Eval retval = null; + String oldStr = null; + String searchStr = null; + String newStr = null; + int numToReplace = REPLACE_ALL; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + case 4: + ValueEval fourthveval = singleOperandEvaluate(operands[3], srcCellRow, srcCellCol); + if (fourthveval instanceof NumericValueEval) { + NumericValueEval numToReplaceEval = (NumericValueEval) fourthveval; + // NOTE: it is safe to cast to int here + // because in Excel =SUBSTITUTE("teststr","t","T",1.9) + // returns Teststr + // so 1.9 must be truncated to 1 + numToReplace = (int) numToReplaceEval.getNumberValue(); + } else { + retval = ErrorEval.VALUE_INVALID; + } + case 3: + // first operand is text string containing characters to replace + // second operand is text to find + // third operand is replacement text + ValueEval firstveval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + ValueEval secondveval = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); + ValueEval thirdveval = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol); + if (firstveval instanceof StringValueEval + && secondveval instanceof StringValueEval + && thirdveval instanceof StringValueEval) { + + StringValueEval oldStrEval = (StringValueEval) firstveval; + oldStr = oldStrEval.getStringValue(); + + StringValueEval searchStrEval = (StringValueEval) secondveval; + searchStr = searchStrEval.getStringValue(); + + StringValueEval newStrEval = (StringValueEval) thirdveval; + newStr = newStrEval.getStringValue(); + } else { + retval = ErrorEval.VALUE_INVALID; + } + } + + if (retval == null) { + if (numToReplace != REPLACE_ALL && numToReplace < 1) { + retval = ErrorEval.VALUE_INVALID; + } else if (searchStr.length() == 0) { + retval = new StringEval(oldStr); + } else { + StringBuffer strBuff = new StringBuffer(); + int startIndex = 0; + int nextMatch = -1; + for (int leftToReplace = numToReplace; + (leftToReplace > 0 || numToReplace == REPLACE_ALL) + && (nextMatch = oldStr.indexOf(searchStr, startIndex)) != -1; + leftToReplace--) { + // store everything from end of last match to start of this match + strBuff.append(oldStr.substring(startIndex, nextMatch)); + strBuff.append(newStr); + startIndex = nextMatch + searchStr.length(); + } + // store everything from end of last match to end of string + if (startIndex < oldStr.length()) { + strBuff.append(oldStr.substring(startIndex)); + } + retval = new StringEval(strBuff.toString()); + } + } + return retval; + } + +} 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 new file mode 100644 index 0000000000..ddfa3ad12a --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Subtotal.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Subtotal extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sum.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sum.java new file mode 100644 index 0000000000..d3dcd9b202 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sum.java @@ -0,0 +1,68 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Sum extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + )); + + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = values.length > 0 ? MathX.sum(values) : 0; + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumif.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumif.java new file mode 100644 index 0000000000..11cb02315e --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sumif.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Sumif extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java new file mode 100644 index 0000000000..9f6eafa4dc --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sumproduct.java @@ -0,0 +1,241 @@ +/* +* 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.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + + +/** + * Implementation for the Excel function SUMPRODUCT

    + * + * Syntax :
    + * SUMPRODUCT ( array1[, array2[, array3[, ...]]]) + * + * + *
    array1, ... arrayN  typically area references, + * possibly cell references or scalar values

    + * + * Let An(i,j) represent the element in the ith row jth column + * of the nth array
    + * Assuming each array has the same dimensions (W, H), the result is defined as:
    + * SUMPRODUCT = Σi: 1..H   + * (  Σj: 1..W   + * (  Πn: 1..N + * An(i,j)  + * )  + * ) + * + * @author Josh Micich + */ +public final class Sumproduct implements Function { + + private static final class EvalEx extends Exception { + private final ErrorEval _error; + + public EvalEx(ErrorEval error) { + _error = error; + } + public ErrorEval getError() { + return _error; + } + } + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + + int maxN = args.length; + + if(maxN < 1) { + return ErrorEval.VALUE_INVALID; + } + Eval firstArg = args[0]; + try { + if(firstArg instanceof NumericValueEval) { + return evaluateSingleProduct(args); + } + if(firstArg instanceof RefEval) { + return evaluateSingleProduct(args); + } + if(firstArg instanceof AreaEval) { + AreaEval ae = (AreaEval) firstArg; + if(ae.isRow() && ae.isColumn()) { + return evaluateSingleProduct(args); + } + return evaluateAreaSumProduct(args); + } + } catch (EvalEx e) { + return e.getError(); + } + throw new RuntimeException("Invalid arg type for SUMPRODUCT: (" + + firstArg.getClass().getName() + ")"); + } + + private Eval evaluateSingleProduct(Eval[] evalArgs) throws EvalEx { + int maxN = evalArgs.length; + + double term = 1D; + for(int n=0; ndouble value for the specified ValueEval. + * @param isScalarProduct false for SUMPRODUCTs over area refs. + * @throws EvalEx 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 EvalEx { + + 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 EvalEx(ErrorEval.VALUE_INVALID); + } + return 0; + } + + if(ve instanceof ErrorEval) { + throw new EvalEx((ErrorEval)ve); + } + if(ve instanceof StringEval) { + if(isScalarProduct) { + throw new EvalEx(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/Sumsq.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumsq.java new file mode 100644 index 0000000000..b74b4161ac --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sumsq.java @@ -0,0 +1,70 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Sumsq extends MultiOperandNumericFunction { + private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = + new ValueEvalToNumericXlator((short) ( + ValueEvalToNumericXlator.BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED + | ValueEvalToNumericXlator.STRING_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED + //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED + //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE + //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED + //| ValueEvalToNumericXlator.BLANK_IS_PARSED + )); + + protected ValueEvalToNumericXlator getXlator() { + return DEFAULT_NUM_XLATOR; + } + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + double[] values = getNumberArray(operands, srcCellRow, srcCellCol); + if (values == null) { + retval = ErrorEval.VALUE_INVALID; + } + else { + double d = MathX.sumsq(values); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java new file mode 100644 index 0000000000..30ad5ec230 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java @@ -0,0 +1,36 @@ +/* +* 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.
    + * Syntax:
    + * SUMX2MY2(arrayX, arrayY)

    + * + * result = Σi: 0..n(xi2-yi2) + * + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + */ +public final class Sumx2my2 extends XYNumericFunction { + + protected double evaluate(double[] xArray, double[] yArray) { + return MathX.sumx2my2(xArray, yArray); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java new file mode 100644 index 0000000000..dfd730d12c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java @@ -0,0 +1,36 @@ +/* +* 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 SUMX2PY2()

    + * + * Calculates the sum of squares in two arrays of the same size.
    + * Syntax:
    + * SUMX2PY2(arrayX, arrayY)

    + * + * result = Σi: 0..n(xi2+yi2) + * + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + */ +public final class Sumx2py2 extends XYNumericFunction { + + protected double evaluate(double[] xArray, double[] yArray) { + return MathX.sumx2py2(xArray, yArray); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java b/src/java/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java new file mode 100644 index 0000000000..a1b2fec9b2 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java @@ -0,0 +1,36 @@ +/* +* 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 SUMXMY2()

    + * + * Calculates the sum of squares of differences between two arrays of the same size.
    + * Syntax:
    + * SUMXMY2(arrayX, arrayY)

    + * + * result = Σi: 0..n(xi-yi)2 + * + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + */ +public final class Sumxmy2 extends XYNumericFunction { + + protected double evaluate(double[] xArray, double[] yArray) { + return MathX.sumxmy2(xArray, yArray); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Syd.java b/src/java/org/apache/poi/hssf/record/formula/functions/Syd.java new file mode 100644 index 0000000000..45347f2d51 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Syd.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Syd extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/T.java b/src/java/org/apache/poi/hssf/record/formula/functions/T.java new file mode 100644 index 0000000000..b322cd985c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/T.java @@ -0,0 +1,55 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; + +public final class T implements Function { + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + switch (args.length) { + default: + return ErrorEval.VALUE_INVALID; + case 1: + break; + } + Eval arg = args[0]; + if (arg instanceof RefEval) { + RefEval re = (RefEval) arg; + arg = re.getInnerValueEval(); + } + + if (arg instanceof StringEval) { + // Text values are returned unmodified + return arg; + } + + if (arg instanceof ErrorEval) { + // Error values also returned unmodified + return arg; + } + // for all other argument types the result is empty string + return StringEval.EMPTY_INSTANCE; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Tan.java b/src/java/org/apache/poi/hssf/record/formula/functions/Tan.java new file mode 100644 index 0000000000..c8d1e33e5c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Tan.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Tan extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = Math.tan(d); + retval = (Double.isNaN(d)) + ? (ValueEval) ErrorEval.VALUE_INVALID + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java b/src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java new file mode 100644 index 0000000000..1cb0e4fa2c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Tanh.java @@ -0,0 +1,67 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Tanh extends NumericFunction { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + double d = 0; + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + d = ne.getNumberValue(); + } + else if (ve instanceof BlankEval) { + // do nothing + } + else { + retval = ErrorEval.NUM_ERROR; + } + } + + if (retval == null) { + d = MathX.tanh(d); + retval = (Double.isNaN(d) || Double.isInfinite(d)) + ? (ValueEval) ErrorEval.NUM_ERROR + : new NumberEval(d); + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Tdist.java b/src/java/org/apache/poi/hssf/record/formula/functions/Tdist.java new file mode 100644 index 0000000000..d2a76de2eb --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Tdist.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Tdist extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Text.java b/src/java/org/apache/poi/hssf/record/formula/functions/Text.java new file mode 100644 index 0000000000..833fa82d00 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Text.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Text extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/TextFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/TextFunction.java new file mode 100644 index 0000000000..9da1776127 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/TextFunction.java @@ -0,0 +1,107 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 22, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.AreaEval; +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.StringValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class TextFunction implements Function { + + protected static final String EMPTY_STRING = ""; + + protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { + ValueEval retval; + if (eval instanceof AreaEval) { + AreaEval ae = (AreaEval) eval; + if (ae.contains(srcRow, srcCol)) { // circular ref! + retval = ErrorEval.CIRCULAR_REF_ERROR; + } + else if (ae.isRow()) { + if (ae.containsColumn(srcCol)) { + ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); + retval = attemptXlateToText(ve); + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else if (ae.isColumn()) { + if (ae.containsRow(srcRow)) { + ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); + retval = attemptXlateToText(ve); + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else { + retval = attemptXlateToText((ValueEval) eval); + } + return retval; + } + + + /** + * converts from Different ValueEval types to StringEval. + * Note: AreaEvals are not handled, if arg is an AreaEval, + * the returned value is ErrorEval.VALUE_INVALID + * @param ve + */ + protected ValueEval attemptXlateToText(ValueEval ve) { + ValueEval retval; + if (ve instanceof StringValueEval) { + retval = ve; + } + else if (ve instanceof RefEval) { + RefEval re = (RefEval) ve; + ValueEval ive = re.getInnerValueEval(); + if (ive instanceof StringValueEval) { + retval = ive; + } + else if (ive instanceof BlankEval) { + retval = ive; + } + else { + retval = ErrorEval.VALUE_INVALID; + } + } + else if (ve instanceof BlankEval) { + retval = ve; + } + else { + retval = ErrorEval.VALUE_INVALID; + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Textref.java b/src/java/org/apache/poi/hssf/record/formula/functions/Textref.java new file mode 100644 index 0000000000..8fa2514f68 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Textref.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Textref extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Time.java b/src/java/org/apache/poi/hssf/record/formula/functions/Time.java new file mode 100644 index 0000000000..2b85da168b --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Time.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Time extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Timevalue.java b/src/java/org/apache/poi/hssf/record/formula/functions/Timevalue.java new file mode 100644 index 0000000000..049bd30ff0 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Timevalue.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Timevalue extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Tinv.java b/src/java/org/apache/poi/hssf/record/formula/functions/Tinv.java new file mode 100644 index 0000000000..dab7dcd0e0 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Tinv.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Tinv extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Today.java b/src/java/org/apache/poi/hssf/record/formula/functions/Today.java new file mode 100644 index 0000000000..6260d20a58 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Today.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Today extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Transpose.java b/src/java/org/apache/poi/hssf/record/formula/functions/Transpose.java new file mode 100644 index 0000000000..cd414ff1c8 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Transpose.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Transpose extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Trend.java b/src/java/org/apache/poi/hssf/record/formula/functions/Trend.java new file mode 100644 index 0000000000..80cece928c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Trend.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Trend extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Trim.java b/src/java/org/apache/poi/hssf/record/formula/functions/Trim.java new file mode 100644 index 0000000000..87e29ee34d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Trim.java @@ -0,0 +1,53 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.OperandResolver; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * An implementation of the TRIM function: + * Removes leading and trailing spaces from value if evaluated operand + * value is string. + * @author Manda Wilson < wilson at c bio dot msk cc dot org > + */ +public final class Trim extends TextFunction { + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + + if(args.length != 1) { + return ErrorEval.VALUE_INVALID; + } + + try { + ValueEval veval = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + + String str = OperandResolver.coerceValueToString(veval); + str = str.trim(); + if(str.length() < 1) { + return StringEval.EMPTY_INSTANCE; + } + return new StringEval(str); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Trimmean.java b/src/java/org/apache/poi/hssf/record/formula/functions/Trimmean.java new file mode 100644 index 0000000000..4775a9ee90 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Trimmean.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Trimmean extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/True.java b/src/java/org/apache/poi/hssf/record/formula/functions/True.java new file mode 100644 index 0000000000..78df7776a1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/True.java @@ -0,0 +1,46 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 6, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BoolEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class True implements Function { + + public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { + ValueEval retval; + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 0: + retval = BoolEval.TRUE; + } + return retval; + } + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Trunc.java b/src/java/org/apache/poi/hssf/record/formula/functions/Trunc.java new file mode 100644 index 0000000000..65fedd126d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Trunc.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Trunc extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ttest.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ttest.java new file mode 100644 index 0000000000..b453043c13 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ttest.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Ttest extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Type.java b/src/java/org/apache/poi/hssf/record/formula/functions/Type.java new file mode 100644 index 0000000000..423038211f --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Type.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Type extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Upper.java b/src/java/org/apache/poi/hssf/record/formula/functions/Upper.java new file mode 100644 index 0000000000..5146a6641c --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Upper.java @@ -0,0 +1,65 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.StringValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class Upper extends TextFunction { + + + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + String s = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + if (ve instanceof StringValueEval) { + StringValueEval sve = (StringValueEval) ve; + s = sve.getStringValue(); + } + else if (ve instanceof BlankEval) {} + else { + retval = ErrorEval.VALUE_INVALID; + break; + } + } + + if (retval == null) { + s = (s == null) ? EMPTY_STRING : s; + retval = new StringEval(s.toUpperCase()); + } + + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Usdollar.java b/src/java/org/apache/poi/hssf/record/formula/functions/Usdollar.java new file mode 100644 index 0000000000..3baf71c9b3 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Usdollar.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Usdollar extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Value.java b/src/java/org/apache/poi/hssf/record/formula/functions/Value.java new file mode 100644 index 0000000000..6772dcf283 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Value.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Value extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Var.java b/src/java/org/apache/poi/hssf/record/formula/functions/Var.java new file mode 100644 index 0000000000..2b0a3b67c7 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Var.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Var extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Vara.java b/src/java/org/apache/poi/hssf/record/formula/functions/Vara.java new file mode 100644 index 0000000000..c484c5a9ea --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Vara.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Vara extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Varp.java b/src/java/org/apache/poi/hssf/record/formula/functions/Varp.java new file mode 100644 index 0000000000..e8c8bd30dc --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Varp.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Varp extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Varpa.java b/src/java/org/apache/poi/hssf/record/formula/functions/Varpa.java new file mode 100644 index 0000000000..290b97de89 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Varpa.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Varpa extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Vdb.java b/src/java/org/apache/poi/hssf/record/formula/functions/Vdb.java new file mode 100644 index 0000000000..5fb594d6ee --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Vdb.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Vdb extends NotImplementedFunction { + +} 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 new file mode 100644 index 0000000000..7d27491df1 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Vlookup.java @@ -0,0 +1,123 @@ +/* ==================================================================== + 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.Eval; +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; +/** + * 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. + * + * Syntax:
    + * VLOOKUP(lookup_value, table_array, col_index_num, range_lookup)

    + * + * lookup_value The value to be found in the first column of the table array.
    + * table_array An area reference for the lookup data.
    + * col_index_num a 1 based index specifying which column value of the lookup data will be returned.
    + * range_lookup If TRUE (default), VLOOKUP finds the largest value less than or equal to + * the lookup_value. If FALSE, only exact matches will be considered
    + * + * @author Josh Micich + */ +public final class Vlookup implements Function { + + private static final class ColumnVector implements ValueVector { + + private final AreaEval _tableArray; + private final int _size; + private final int _columnAbsoluteIndex; + private final int _firstRowAbsoluteIndex; + + public ColumnVector(AreaEval tableArray, int columnIndex) { + _columnAbsoluteIndex = tableArray.getFirstColumn() + columnIndex; + if(!tableArray.containsColumn((short)_columnAbsoluteIndex)) { + int lastColIx = tableArray.getLastColumn() - tableArray.getFirstColumn(); + throw new IllegalArgumentException("Specified column index (" + columnIndex + + ") is outside the allowed range (0.." + lastColIx + ")"); + } + _tableArray = tableArray; + _size = tableArray.getLastRow() - tableArray.getFirstRow() + 1; + if(_size < 1) { + throw new RuntimeException("bad table array size zero"); + } + _firstRowAbsoluteIndex = tableArray.getFirstRow(); + } + + public ValueEval getItem(int index) { + if(index>_size) { + throw new ArrayIndexOutOfBoundsException("Specified index (" + index + + ") is outside the allowed range (0.." + (_size-1) + ")"); + } + return _tableArray.getValueAt(_firstRowAbsoluteIndex + index, (short)_columnAbsoluteIndex); + } + public int getSize() { + return _size; + } + } + + public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + Eval arg3 = null; + switch(args.length) { + case 4: + arg3 = args[3]; // important: assumed array element is never null + case 3: + break; + default: + // wrong number of arguments + return ErrorEval.VALUE_INVALID; + } + try { + // Evaluation order: + // arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 col_index, fetch result + ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); + AreaEval tableArray = LookupUtils.resolveTableArrayArg(args[1]); + boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcCellRow, srcCellCol); + int rowIndex = LookupUtils.lookupIndexOfValue(lookupValue, new ColumnVector(tableArray, 0), isRangeLookup); + ValueEval veColIndex = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol); + int colIndex = LookupUtils.resolveRowOrColIndexArg(veColIndex); + ValueVector resultCol = createResultColumnVector(tableArray, colIndex); + return resultCol.getItem(rowIndex); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + } + + + /** + * Returns one column from an AreaEval + * + * @throws EvaluationException (#VALUE!) if colIndex is negative, (#REF!) if colIndex is too high + */ + private ValueVector createResultColumnVector(AreaEval tableArray, int colIndex) throws EvaluationException { + if(colIndex < 0) { + throw EvaluationException.invalidValue(); + } + int nCols = tableArray.getLastColumn() - tableArray.getFirstColumn() + 1; + + if(colIndex >= nCols) { + throw EvaluationException.invalidRef(); + } + return new ColumnVector(tableArray, colIndex); + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Volatile.java b/src/java/org/apache/poi/hssf/record/formula/functions/Volatile.java new file mode 100644 index 0000000000..734eb0fbe7 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Volatile.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Volatile extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Weekday.java b/src/java/org/apache/poi/hssf/record/formula/functions/Weekday.java new file mode 100644 index 0000000000..7de5f952b3 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Weekday.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Weekday extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Weibull.java b/src/java/org/apache/poi/hssf/record/formula/functions/Weibull.java new file mode 100644 index 0000000000..b2a4895fad --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Weibull.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Weibull extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java b/src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java new file mode 100644 index 0000000000..b989c33a26 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java @@ -0,0 +1,203 @@ +/* +* 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.Eval; +import org.apache.poi.hssf.record.formula.eval.EvaluationException; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class XYNumericFunction implements Function { + protected static final int X = 0; + protected static final int Y = 1; + + protected static final class DoubleArrayPair { + + private final double[] _xArray; + private final double[] _yArray; + + public DoubleArrayPair(double[] xArray, double[] yArray) { + _xArray = xArray; + _yArray = yArray; + } + public double[] getXArray() { + return _xArray; + } + public double[] getYArray() { + return _yArray; + } + } + + + public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { + if(args.length != 2) { + return ErrorEval.VALUE_INVALID; + } + + double[][] values; + try { + values = getValues(args[0], args[1]); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + if (values==null + || values[X] == null || values[Y] == null + || values[X].length == 0 || values[Y].length == 0 + || values[X].length != values[Y].length) { + return ErrorEval.VALUE_INVALID; + } + + double d = evaluate(values[X], values[Y]); + if (Double.isNaN(d) || Double.isInfinite(d)) { + return ErrorEval.NUM_ERROR; + } + return new NumberEval(d); + } + protected abstract double evaluate(double[] xArray, double[] yArray); + + /** + * Returns a double array that contains values for the numeric cells + * from among the list of operands. Blanks and Blank equivalent cells + * are ignored. Error operands or cells containing operands of type + * that are considered invalid and would result in #VALUE! error in + * excel cause this function to return null. + */ + private static double[][] getNumberArray(Eval[] xops, Eval[] yops) throws EvaluationException { + + // check for errors first: size mismatch, value errors in x, value errors in y + + int nArrayItems = xops.length; + if(nArrayItems != yops.length) { + throw new EvaluationException(ErrorEval.NA); + } + for (int i = 0; i < xops.length; i++) { + Eval eval = xops[i]; + if (eval instanceof ErrorEval) { + throw new EvaluationException((ErrorEval) eval); + } + } + for (int i = 0; i < yops.length; i++) { + Eval eval = yops[i]; + if (eval instanceof ErrorEval) { + throw new EvaluationException((ErrorEval) eval); + } + } + + double[] xResult = new double[nArrayItems]; + double[] yResult = new double[nArrayItems]; + + int count = 0; + + for (int i=0, iSize=nArrayItems; i len) { + tarr = new double[len]; + System.arraycopy(arr, 0, tarr, 0, len); + } + return tarr; + } + + private static boolean isNumberEval(Eval eval) { + boolean retval = false; + + if (eval instanceof NumberEval) { + retval = true; + } + else if (eval instanceof RefEval) { + RefEval re = (RefEval) eval; + ValueEval ve = re.getInnerValueEval(); + retval = (ve instanceof NumberEval); + } + + return retval; + } + + private static double getDoubleValue(Eval eval) { + double retval = 0; + if (eval instanceof NumberEval) { + NumberEval ne = (NumberEval) eval; + retval = ne.getNumberValue(); + } + else if (eval instanceof RefEval) { + RefEval re = (RefEval) eval; + ValueEval ve = re.getInnerValueEval(); + retval = (ve instanceof NumberEval) + ? ((NumberEval) ve).getNumberValue() + : Double.NaN; + } + else if (eval instanceof ErrorEval) { + retval = Double.NaN; + } + return retval; + } +} diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Year.java b/src/java/org/apache/poi/hssf/record/formula/functions/Year.java new file mode 100644 index 0000000000..b461a09668 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Year.java @@ -0,0 +1,68 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.BlankEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; + +/** + * + * @author Guenter Kickinger g.kickinger@gmx.net + * + */ + +public class Year extends NumericFunction { + + /* (non-Javadoc) + * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) + */ + public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { + ValueEval retval = null; + + switch (operands.length) { + default: + retval = ErrorEval.VALUE_INVALID; + break; + case 1: + ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); + if (ve instanceof NumericValueEval) { + NumericValueEval ne = (NumericValueEval) ve; + if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { + java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem + retval = new NumberEval(d.getYear()+1900); + } else { + retval = ErrorEval.NUM_ERROR; + } + } + else if (ve instanceof BlankEval) { + // do nothing + } else { + retval = ErrorEval.NUM_ERROR; + } + } + return retval; + } +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Ztest.java b/src/java/org/apache/poi/hssf/record/formula/functions/Ztest.java new file mode 100644 index 0000000000..ed12b63328 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Ztest.java @@ -0,0 +1,25 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * Created on May 15, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +public class Ztest extends NotImplementedFunction { + +} diff --git a/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java b/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java new file mode 100755 index 0000000000..90f5807ff5 --- /dev/null +++ b/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java @@ -0,0 +1,150 @@ +/* ==================================================================== + 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.usermodel; + +import java.util.ArrayList; +import java.util.List; + +/** + * Instances of this class keep track of multiple dependent cell evaluations due + * to recursive calls to HSSFFormulaEvaluator.internalEvaluate(). + * The main purpose of this class is to detect an attempt to evaluate a cell + * that is already being evaluated. In other words, it detects circular + * references in spreadsheet formulas. + * + * @author Josh Micich + */ +final class EvaluationCycleDetector { + + /** + * Stores the parameters that identify the evaluation of one cell.
    + */ + private static final class CellEvaluationFrame { + + private final HSSFWorkbook _workbook; + private final HSSFSheet _sheet; + private final int _srcRowNum; + private final int _srcColNum; + + public CellEvaluationFrame(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { + if (workbook == null) { + throw new IllegalArgumentException("workbook must not be null"); + } + if (sheet == null) { + throw new IllegalArgumentException("sheet must not be null"); + } + _workbook = workbook; + _sheet = sheet; + _srcRowNum = srcRowNum; + _srcColNum = srcColNum; + } + + public boolean equals(Object obj) { + CellEvaluationFrame other = (CellEvaluationFrame) obj; + if (_workbook != other._workbook) { + return false; + } + if (_sheet != other._sheet) { + return false; + } + if (_srcRowNum != other._srcRowNum) { + return false; + } + if (_srcColNum != other._srcColNum) { + return false; + } + return true; + } + + /** + * @return human readable string for debug purposes + */ + public String formatAsString() { + return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _workbook.getSheetIndex(_sheet); + } + + public String toString() { + StringBuffer sb = new StringBuffer(64); + sb.append(getClass().getName()).append(" ["); + sb.append(formatAsString()); + sb.append("]"); + return sb.toString(); + } + } + + private final List _evaluationFrames; + + public EvaluationCycleDetector() { + _evaluationFrames = new ArrayList(); + } + + /** + * Notifies this evaluation tracker that evaluation of the specified cell is + * about to start.
    + * + * In the case of a true return code, the caller should + * continue evaluation of the specified cell, and also be sure to call + * endEvaluate() when complete.
    + * + * In the case of a false return code, the caller should + * return an evaluation result of + * ErrorEval.CIRCULAR_REF_ERROR, and not call endEvaluate(). + *
    + * @return true if the specified cell has not been visited yet in the current + * evaluation. false if the specified cell is already being evaluated. + */ + public boolean startEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { + CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum); + if (_evaluationFrames.contains(cef)) { + return false; + } + _evaluationFrames.add(cef); + return true; + } + + /** + * Notifies this evaluation tracker that the evaluation of the specified + * cell is complete.

    + * + * Every successful call to startEvaluate must be followed by a + * call to endEvaluate (recommended in a finally block) to enable + * proper tracking of which cells are being evaluated at any point in time.

    + * + * Assuming a well behaved client, parameters to this method would not be + * required. However, they have been included to assert correct behaviour, + * and form more meaningful error messages. + */ + public void endEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { + int nFrames = _evaluationFrames.size(); + if (nFrames < 1) { + throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate"); + } + + nFrames--; + CellEvaluationFrame cefExpected = (CellEvaluationFrame) _evaluationFrames.get(nFrames); + CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum); + if (!cefActual.equals(cefExpected)) { + throw new RuntimeException("Wrong cell specified. " + + "Corresponding startEvaluate() call was for cell {" + + cefExpected.formatAsString() + "} this endEvaluate() call is for cell {" + + cefActual.formatAsString() + "}"); + } + // else - no problems so pop current frame + _evaluationFrames.remove(nFrames); + } +} diff --git a/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetectorManager.java b/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetectorManager.java new file mode 100755 index 0000000000..a06cd201e2 --- /dev/null +++ b/src/java/org/apache/poi/hssf/usermodel/EvaluationCycleDetectorManager.java @@ -0,0 +1,46 @@ +/* ==================================================================== + 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.usermodel; + +/** + * This class makes an EvaluationCycleDetector instance available to + * each thread via a ThreadLocal in order to avoid adding a parameter + * to a few protected methods within HSSFFormulaEvaluator. + * + * @author Josh Micich + */ +final class EvaluationCycleDetectorManager { + + ThreadLocal tl = null; + private static ThreadLocal _tlEvaluationTracker = new ThreadLocal() { + protected synchronized Object initialValue() { + return new EvaluationCycleDetector(); + } + }; + + /** + * @return + */ + public static EvaluationCycleDetector getTracker() { + return (EvaluationCycleDetector) _tlEvaluationTracker.get(); + } + + private EvaluationCycleDetectorManager() { + // no instances of this class + } +} diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java new file mode 100644 index 0000000000..bb16fdfadd --- /dev/null +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java @@ -0,0 +1,778 @@ +/* +* 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.usermodel; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Stack; + +import org.apache.poi.hssf.model.FormulaParser; +import org.apache.poi.hssf.model.Workbook; +import org.apache.poi.hssf.record.formula.Area3DPtg; +import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.hssf.record.formula.AttrPtg; +import org.apache.poi.hssf.record.formula.BoolPtg; +import org.apache.poi.hssf.record.formula.ControlPtg; +import org.apache.poi.hssf.record.formula.IntPtg; +import org.apache.poi.hssf.record.formula.MemErrPtg; +import org.apache.poi.hssf.record.formula.MissingArgPtg; +import org.apache.poi.hssf.record.formula.NamePtg; +import org.apache.poi.hssf.record.formula.NameXPtg; +import org.apache.poi.hssf.record.formula.NumberPtg; +import org.apache.poi.hssf.record.formula.OperationPtg; +import org.apache.poi.hssf.record.formula.ParenthesisPtg; +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.record.formula.Ref3DPtg; +import org.apache.poi.hssf.record.formula.ReferencePtg; +import org.apache.poi.hssf.record.formula.StringPtg; +import org.apache.poi.hssf.record.formula.UnionPtg; +import org.apache.poi.hssf.record.formula.UnknownPtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +import org.apache.poi.hssf.record.formula.eval.Area3DEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.FunctionEval; +import org.apache.poi.hssf.record.formula.eval.NameEval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.OperationEval; +import org.apache.poi.hssf.record.formula.eval.Ref2DEval; +import org.apache.poi.hssf.record.formula.eval.Ref3DEval; +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 > + * + */ +public class HSSFFormulaEvaluator { + + // params to lookup the right constructor using reflection + private static final Class[] VALUE_CONTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class }; + + private static final Class[] AREA3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval[].class }; + + private static final Class[] REFERENCE_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class }; + + private static final Class[] REF3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class }; + + // Maps for mapping *Eval to *Ptg + private static final Map VALUE_EVALS_MAP = new HashMap(); + + /* + * Following is the mapping between the Ptg tokens returned + * by the FormulaParser and the *Eval classes that are used + * by the FormulaEvaluator + */ + static { + VALUE_EVALS_MAP.put(BoolPtg.class, BoolEval.class); + VALUE_EVALS_MAP.put(IntPtg.class, NumberEval.class); + VALUE_EVALS_MAP.put(NumberPtg.class, NumberEval.class); + VALUE_EVALS_MAP.put(StringPtg.class, StringEval.class); + + } + + + protected HSSFRow row; + protected HSSFSheet sheet; + protected HSSFWorkbook workbook; + + public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) { + this.sheet = sheet; + this.workbook = workbook; + } + + public void setCurrentRow(HSSFRow row) { + this.row = row; + } + + + /** + * Returns an underlying FormulaParser, for the specified + * Formula String and HSSFWorkbook. + * This will allow you to generate the Ptgs yourself, if + * your needs are more complex than just having the + * formula evaluated. + */ + public static FormulaParser getUnderlyingParser(HSSFWorkbook workbook, String formula) { + return new FormulaParser(formula, workbook.getWorkbook()); + } + + /** + * If cell contains a formula, the formula is evaluated and returned, + * else the CellValue simply copies the appropriate cell value from + * the cell and also its cell type. This method should be preferred over + * evaluateInCell() when the call should not modify the contents of the + * original cell. + * @param cell + */ + public CellValue evaluate(HSSFCell cell) { + CellValue retval = null; + if (cell != null) { + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_BLANK: + retval = new CellValue(HSSFCell.CELL_TYPE_BLANK); + break; + case HSSFCell.CELL_TYPE_BOOLEAN: + retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN); + retval.setBooleanValue(cell.getBooleanCellValue()); + break; + case HSSFCell.CELL_TYPE_ERROR: + retval = new CellValue(HSSFCell.CELL_TYPE_ERROR); + retval.setErrorValue(cell.getErrorCellValue()); + break; + case HSSFCell.CELL_TYPE_FORMULA: + retval = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook)); + break; + case HSSFCell.CELL_TYPE_NUMERIC: + retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC); + retval.setNumberValue(cell.getNumericCellValue()); + break; + case HSSFCell.CELL_TYPE_STRING: + retval = new CellValue(HSSFCell.CELL_TYPE_STRING); + retval.setRichTextStringValue(cell.getRichStringCellValue()); + break; + } + } + return retval; + } + + + /** + * If cell contains formula, it evaluates the formula, + * and saves the result of the formula. The cell + * remains as a formula cell. + * Else if cell does not contain formula, this method leaves + * the cell unchanged. + * Note that the type of the formula result is returned, + * so you know what kind of value is also stored with + * the formula. + *

    +     * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
    +     * 
    + * Be aware that your cell will hold both the formula, + * and the result. If you want the cell replaced with + * the result of the formula, use {@link #evaluateInCell(HSSFCell)} + * @param cell The cell to evaluate + * @return The type of the formula result (the cell's type remains as HSSFCell.CELL_TYPE_FORMULA however) + */ + public int evaluateFormulaCell(HSSFCell cell) { + if (cell != null) { + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_FORMULA: + CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook)); + switch (cv.getCellType()) { + case HSSFCell.CELL_TYPE_BOOLEAN: + cell.setCellValue(cv.getBooleanValue()); + break; + case HSSFCell.CELL_TYPE_ERROR: + cell.setCellValue(cv.getErrorValue()); + break; + case HSSFCell.CELL_TYPE_NUMERIC: + cell.setCellValue(cv.getNumberValue()); + break; + case HSSFCell.CELL_TYPE_STRING: + cell.setCellValue(cv.getRichTextStringValue()); + break; + case HSSFCell.CELL_TYPE_BLANK: + break; + case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula + break; + } + return cv.getCellType(); + } + } + return -1; + } + + /** + * If cell contains formula, it evaluates the formula, and + * puts the formula result back into the cell, in place + * of the old formula. + * Else if cell does not contain formula, this method leaves + * the cell unchanged. + * Note that the same instance of HSSFCell is returned to + * allow chained calls like: + *
    +     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
    +     * 
    + * Be aware that your cell value will be changed to hold the + * result of the formula. If you simply want the formula + * value computed for you, use {@link #evaluateFormulaCell(HSSFCell)} + * @param cell + */ + public HSSFCell evaluateInCell(HSSFCell cell) { + if (cell != null) { + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_FORMULA: + CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook)); + switch (cv.getCellType()) { + case HSSFCell.CELL_TYPE_BOOLEAN: + cell.setCellType(HSSFCell.CELL_TYPE_BOOLEAN); + cell.setCellValue(cv.getBooleanValue()); + break; + case HSSFCell.CELL_TYPE_ERROR: + cell.setCellType(HSSFCell.CELL_TYPE_ERROR); + cell.setCellValue(cv.getErrorValue()); + break; + case HSSFCell.CELL_TYPE_NUMERIC: + cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); + cell.setCellValue(cv.getNumberValue()); + break; + case HSSFCell.CELL_TYPE_STRING: + cell.setCellType(HSSFCell.CELL_TYPE_STRING); + cell.setCellValue(cv.getRichTextStringValue()); + break; + case HSSFCell.CELL_TYPE_BLANK: + break; + case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula + break; + } + } + } + return cell; + } + + /** + * Loops over all cells in all sheets of the supplied + * workbook. + * For cells that contain formulas, their formulas are + * evaluated, and the results are saved. These cells + * remain as formula cells. + * For cells that do not contain formulas, no changes + * are made. + * This is a helpful wrapper around looping over all + * cells, and calling evaluateFormulaCell on each one. + */ + public static void evaluateAllFormulaCells(HSSFWorkbook wb) { + for(int i=0; i= 0; j--) { + Eval p = (Eval) stack.pop(); + ops[j] = p; + } + Eval opresult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet); + stack.push(opresult); + } + else if (ptg instanceof ReferencePtg) { + ReferencePtg refPtg = (ReferencePtg) ptg; + int colIx = refPtg.getColumn(); + int rowIx = refPtg.getRow(); + HSSFRow row = sheet.getRow(rowIx); + HSSFCell cell = (row != null) ? row.getCell(colIx) : null; + stack.push(createRef2DEval(refPtg, cell, row, sheet, workbook)); + } + else if (ptg instanceof Ref3DPtg) { + Ref3DPtg refPtg = (Ref3DPtg) ptg; + int colIx = refPtg.getColumn(); + int rowIx = refPtg.getRow(); + Workbook wb = workbook.getWorkbook(); + HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex())); + HSSFRow row = xsheet.getRow(rowIx); + HSSFCell cell = (row != null) ? row.getCell(colIx) : null; + stack.push(createRef3DEval(refPtg, cell, row, xsheet, workbook)); + } + else if (ptg instanceof AreaPtg) { + AreaPtg ap = (AreaPtg) ptg; + AreaEval ae = evaluateAreaPtg(sheet, workbook, ap); + stack.push(ae); + } + else if (ptg instanceof Area3DPtg) { + Area3DPtg a3dp = (Area3DPtg) ptg; + AreaEval ae = evaluateArea3dPtg(workbook, a3dp); + stack.push(ae); + } + else { + Eval ptgEval = getEvalForPtg(ptg); + stack.push(ptgEval); + } + } + + ValueEval value = ((ValueEval) stack.pop()); + if (!stack.isEmpty()) { + throw new IllegalStateException("evaluation stack not empty"); + } + value = dereferenceValue(value, srcRowNum, srcColNum); + if (value instanceof BlankEval) { + // Note Excel behaviour here. A blank final final value is converted to zero. + return NumberEval.ZERO; + // Formulas _never_ evaluate to blank. If a formula appears to have evaluated to + // blank, the actual value is empty string. This can be verified with ISBLANK(). + } + return value; + } + + /** + * Dereferences a single value from any AreaEval or RefEval evaluation result. + * If the supplied evaluationResult is just a plain value, it is returned as-is. + * @return a NumberEval, StringEval, BoolEval, + * BlankEval or ErrorEval. Never null. + */ + private static ValueEval dereferenceValue(ValueEval evaluationResult, int srcRowNum, short srcColNum) { + if (evaluationResult instanceof RefEval) { + RefEval rv = (RefEval) evaluationResult; + return rv.getInnerValueEval(); + } + if (evaluationResult instanceof AreaEval) { + AreaEval ae = (AreaEval) evaluationResult; + if (ae.isRow()) { + if(ae.isColumn()) { + return ae.getValues()[0]; + } + return ae.getValueAt(ae.getFirstRow(), srcColNum); + } + if (ae.isColumn()) { + return ae.getValueAt(srcRowNum, ae.getFirstColumn()); + } + return ErrorEval.VALUE_INVALID; + } + return evaluationResult; + } + + private static Eval invokeOperation(OperationEval operation, Eval[] ops, int srcRowNum, short srcColNum, + HSSFWorkbook workbook, HSSFSheet sheet) { + + if(operation instanceof FunctionEval) { + FunctionEval fe = (FunctionEval) operation; + if(fe.isFreeRefFunction()) { + return fe.getFreeRefFunction().evaluate(ops, srcRowNum, srcColNum, workbook, sheet); + } + } + return operation.evaluate(ops, srcRowNum, srcColNum); + } + + public static AreaEval evaluateAreaPtg(HSSFSheet sheet, HSSFWorkbook workbook, AreaPtg ap) { + int row0 = ap.getFirstRow(); + int col0 = ap.getFirstColumn(); + int row1 = ap.getLastRow(); + int col1 = ap.getLastColumn(); + + // If the last row is -1, then the + // reference is for the rest of the column + // (eg C:C) + // TODO: Handle whole column ranges properly + if(row1 == -1 && row0 >= 0) { + row1 = (short)sheet.getLastRowNum(); + } + ValueEval[] values = evalArea(workbook, sheet, row0, col0, row1, col1); + return new Area2DEval(ap, values); + } + + public static AreaEval evaluateArea3dPtg(HSSFWorkbook workbook, Area3DPtg a3dp) { + int row0 = a3dp.getFirstRow(); + int col0 = a3dp.getFirstColumn(); + int row1 = a3dp.getLastRow(); + int col1 = a3dp.getLastColumn(); + Workbook wb = workbook.getWorkbook(); + HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex())); + + // If the last row is -1, then the + // reference is for the rest of the column + // (eg C:C) + // TODO: Handle whole column ranges properly + if(row1 == -1 && row0 >= 0) { + row1 = (short)xsheet.getLastRowNum(); + } + + ValueEval[] values = evalArea(workbook, xsheet, row0, col0, row1, col1); + return new Area3DEval(a3dp, values); + } + + private static ValueEval[] evalArea(HSSFWorkbook workbook, HSSFSheet sheet, + int row0, int col0, int row1, int col1) { + ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)]; + for (int x = row0; sheet != null && x < row1 + 1; x++) { + HSSFRow row = sheet.getRow(x); + for (int y = col0; y < col1 + 1; y++) { + ValueEval cellEval; + if(row == null) { + cellEval = BlankEval.INSTANCE; + } else { + cellEval = getEvalForCell(row.getCell(y), row, sheet, workbook); + } + values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = cellEval; + } + } + return values; + } + + /** + * returns an appropriate Eval impl instance for the Ptg. The Ptg must be + * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg, + * StringPtg, BoolPtg
    special Note: OperationPtg subtypes cannot be + * passed here! + * + * @param ptg + */ + protected static Eval getEvalForPtg(Ptg ptg) { + Eval retval = null; + + Class clazz = (Class) VALUE_EVALS_MAP.get(ptg.getClass()); + try { + if (ptg instanceof Area3DPtg) { + Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY); + retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); + } + else if (ptg instanceof AreaPtg) { + Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY); + retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); + } + else if (ptg instanceof ReferencePtg) { + Constructor constructor = clazz.getConstructor(REFERENCE_CONSTRUCTOR_CLASS_ARRAY); + retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); + } + else if (ptg instanceof Ref3DPtg) { + Constructor constructor = clazz.getConstructor(REF3D_CONSTRUCTOR_CLASS_ARRAY); + retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); + } + else { + if (ptg instanceof IntPtg || ptg instanceof NumberPtg || ptg instanceof StringPtg + || ptg instanceof BoolPtg) { + Constructor constructor = clazz.getConstructor(VALUE_CONTRUCTOR_CLASS_ARRAY); + retval = (ValueEval) constructor.newInstance(new Ptg[] { ptg }); + } + } + } + catch (Exception e) { + throw new RuntimeException("Fatal Error: ", e); + } + return retval; + + } + + /** + * Given a cell, find its type and from that create an appropriate ValueEval + * impl instance and return that. Since the cell could be an external + * reference, we need the sheet that this belongs to. + * Non existent cells are treated as empty. + * @param cell + * @param sheet + * @param workbook + */ + protected static ValueEval getEvalForCell(HSSFCell cell, HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) { + + if (cell == null) { + return BlankEval.INSTANCE; + } + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_NUMERIC: + return new NumberEval(cell.getNumericCellValue()); + case HSSFCell.CELL_TYPE_STRING: + return new StringEval(cell.getRichStringCellValue().getString()); + case HSSFCell.CELL_TYPE_FORMULA: + return internalEvaluate(cell, row, sheet, workbook); + case HSSFCell.CELL_TYPE_BOOLEAN: + return BoolEval.valueOf(cell.getBooleanCellValue()); + case HSSFCell.CELL_TYPE_BLANK: + return BlankEval.INSTANCE; + case HSSFCell.CELL_TYPE_ERROR: + return ErrorEval.valueOf(cell.getErrorCellValue()); + } + throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")"); + } + + /** + * Creates a Ref2DEval for ReferencePtg. + * Non existent cells are treated as RefEvals containing BlankEval. + */ + private static Ref2DEval createRef2DEval(ReferencePtg ptg, HSSFCell cell, + HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) { + if (cell == null) { + return new Ref2DEval(ptg, BlankEval.INSTANCE); + } + + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_NUMERIC: + return new Ref2DEval(ptg, new NumberEval(cell.getNumericCellValue())); + case HSSFCell.CELL_TYPE_STRING: + return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString())); + case HSSFCell.CELL_TYPE_FORMULA: + return new Ref2DEval(ptg, internalEvaluate(cell, row, sheet, workbook)); + case HSSFCell.CELL_TYPE_BOOLEAN: + return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue())); + case HSSFCell.CELL_TYPE_BLANK: + return new Ref2DEval(ptg, BlankEval.INSTANCE); + case HSSFCell.CELL_TYPE_ERROR: + return new Ref2DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue())); + } + throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")"); + } + + /** + * create a Ref3DEval for Ref3DPtg. + */ + private static Ref3DEval createRef3DEval(Ref3DPtg ptg, HSSFCell cell, + HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) { + if (cell == null) { + return new Ref3DEval(ptg, BlankEval.INSTANCE); + } + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_NUMERIC: + return new Ref3DEval(ptg, new NumberEval(cell.getNumericCellValue())); + case HSSFCell.CELL_TYPE_STRING: + return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString())); + case HSSFCell.CELL_TYPE_FORMULA: + return new Ref3DEval(ptg, internalEvaluate(cell, row, sheet, workbook)); + case HSSFCell.CELL_TYPE_BOOLEAN: + return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue())); + case HSSFCell.CELL_TYPE_BLANK: + return new Ref3DEval(ptg, BlankEval.INSTANCE); + case HSSFCell.CELL_TYPE_ERROR: + return new Ref3DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue())); + } + throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")"); + } + + /** + * Mimics the 'data view' of a cell. This allows formula evaluator + * to return a CellValue instead of precasting the value to String + * or Number or boolean type. + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + */ + public static final class CellValue { + private int cellType; + private HSSFRichTextString richTextStringValue; + private double numberValue; + private boolean booleanValue; + private byte errorValue; + + /** + * CellType should be one of the types defined in HSSFCell + * @param cellType + */ + public CellValue(int cellType) { + super(); + this.cellType = cellType; + } + /** + * @return Returns the booleanValue. + */ + public boolean getBooleanValue() { + return booleanValue; + } + /** + * @param booleanValue The booleanValue to set. + */ + public void setBooleanValue(boolean booleanValue) { + this.booleanValue = booleanValue; + } + /** + * @return Returns the numberValue. + */ + public double getNumberValue() { + return numberValue; + } + /** + * @param numberValue The numberValue to set. + */ + public void setNumberValue(double numberValue) { + this.numberValue = numberValue; + } + /** + * @return Returns the stringValue. This method is deprecated, use + * getRichTextStringValue instead + * @deprecated + */ + public String getStringValue() { + return richTextStringValue.getString(); + } + /** + * @param stringValue The stringValue to set. This method is deprecated, use + * getRichTextStringValue instead. + * @deprecated + */ + public void setStringValue(String stringValue) { + this.richTextStringValue = new HSSFRichTextString(stringValue); + } + /** + * @return Returns the cellType. + */ + public int getCellType() { + return cellType; + } + /** + * @return Returns the errorValue. + */ + public byte getErrorValue() { + return errorValue; + } + /** + * @param errorValue The errorValue to set. + */ + public void setErrorValue(byte errorValue) { + this.errorValue = errorValue; + } + /** + * @return Returns the richTextStringValue. + */ + public HSSFRichTextString getRichTextStringValue() { + return richTextStringValue; + } + /** + * @param richTextStringValue The richTextStringValue to set. + */ + public void setRichTextStringValue(HSSFRichTextString richTextStringValue) { + this.richTextStringValue = richTextStringValue; + } + } + + /** + * debug method + * + * @param formula + * @param sheet + * @param workbook + */ + void inspectPtgs(String formula) { + FormulaParser fp = new FormulaParser(formula, workbook.getWorkbook()); + fp.parse(); + Ptg[] ptgs = fp.getRPNPtg(); + System.out.println(""); + for (int i = 0, iSize = ptgs.length; i < iSize; i++) { + System.out.println(""); + System.out.println(ptgs[i]); + if (ptgs[i] instanceof OperationPtg) { + System.out.println("numoperands: " + ((OperationPtg) ptgs[i]).getNumberOfOperands()); + } + System.out.println(""); + } + System.out.println(""); + } + +} diff --git a/src/java/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java b/src/java/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java new file mode 100755 index 0000000000..1292009699 --- /dev/null +++ b/src/java/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java @@ -0,0 +1,165 @@ +/* ==================================================================== + 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.usermodel; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +import org.apache.poi.hssf.record.formula.AddPtg; +import org.apache.poi.hssf.record.formula.ConcatPtg; +import org.apache.poi.hssf.record.formula.DividePtg; +import org.apache.poi.hssf.record.formula.EqualPtg; +import org.apache.poi.hssf.record.formula.ExpPtg; +import org.apache.poi.hssf.record.formula.FuncPtg; +import org.apache.poi.hssf.record.formula.FuncVarPtg; +import org.apache.poi.hssf.record.formula.GreaterEqualPtg; +import org.apache.poi.hssf.record.formula.GreaterThanPtg; +import org.apache.poi.hssf.record.formula.LessEqualPtg; +import org.apache.poi.hssf.record.formula.LessThanPtg; +import org.apache.poi.hssf.record.formula.MultiplyPtg; +import org.apache.poi.hssf.record.formula.NotEqualPtg; +import org.apache.poi.hssf.record.formula.OperationPtg; +import org.apache.poi.hssf.record.formula.PercentPtg; +import org.apache.poi.hssf.record.formula.PowerPtg; +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.record.formula.SubtractPtg; +import org.apache.poi.hssf.record.formula.UnaryMinusPtg; +import org.apache.poi.hssf.record.formula.UnaryPlusPtg; +import org.apache.poi.hssf.record.formula.eval.AddEval; +import org.apache.poi.hssf.record.formula.eval.ConcatEval; +import org.apache.poi.hssf.record.formula.eval.DivideEval; +import org.apache.poi.hssf.record.formula.eval.EqualEval; +import org.apache.poi.hssf.record.formula.eval.FuncVarEval; +import org.apache.poi.hssf.record.formula.eval.GreaterEqualEval; +import org.apache.poi.hssf.record.formula.eval.GreaterThanEval; +import org.apache.poi.hssf.record.formula.eval.LessEqualEval; +import org.apache.poi.hssf.record.formula.eval.LessThanEval; +import org.apache.poi.hssf.record.formula.eval.MultiplyEval; +import org.apache.poi.hssf.record.formula.eval.NotEqualEval; +import org.apache.poi.hssf.record.formula.eval.OperationEval; +import org.apache.poi.hssf.record.formula.eval.PercentEval; +import org.apache.poi.hssf.record.formula.eval.PowerEval; +import org.apache.poi.hssf.record.formula.eval.SubtractEval; +import org.apache.poi.hssf.record.formula.eval.UnaryMinusEval; +import org.apache.poi.hssf.record.formula.eval.UnaryPlusEval; + +/** + * This class creates OperationEval instances to help evaluate OperationPtg + * formula tokens. + * + * @author Josh Micich + */ +final class OperationEvaluatorFactory { + private static final Class[] OPERATION_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class }; + + private static final Map _constructorsByPtgClass = initialiseConstructorsMap(); + + private OperationEvaluatorFactory() { + // no instances of this class + } + + private static Map initialiseConstructorsMap() { + Map m = new HashMap(32); + add(m, AddPtg.class, AddEval.class); + add(m, ConcatPtg.class, ConcatEval.class); + add(m, DividePtg.class, DivideEval.class); + add(m, EqualPtg.class, EqualEval.class); + add(m, FuncPtg.class, FuncVarEval.class); + add(m, FuncVarPtg.class, FuncVarEval.class); + add(m, GreaterEqualPtg.class, GreaterEqualEval.class); + add(m, GreaterThanPtg.class, GreaterThanEval.class); + add(m, LessEqualPtg.class, LessEqualEval.class); + add(m, LessThanPtg.class, LessThanEval.class); + add(m, MultiplyPtg.class, MultiplyEval.class); + add(m, NotEqualPtg.class, NotEqualEval.class); + add(m, PercentPtg.class, PercentEval.class); + add(m, PowerPtg.class, PowerEval.class); + add(m, SubtractPtg.class, SubtractEval.class); + add(m, UnaryMinusPtg.class, UnaryMinusEval.class); + add(m, UnaryPlusPtg.class, UnaryPlusEval.class); + return m; + } + + private static void add(Map m, Class ptgClass, Class evalClass) { + + // perform some validation now, to keep later exception handlers simple + if(!Ptg.class.isAssignableFrom(ptgClass)) { + throw new IllegalArgumentException("Expected Ptg subclass"); + } + if(!OperationEval.class.isAssignableFrom(evalClass)) { + throw new IllegalArgumentException("Expected OperationEval subclass"); + } + if (!Modifier.isPublic(evalClass.getModifiers())) { + throw new RuntimeException("Eval class must be public"); + } + if (Modifier.isAbstract(evalClass.getModifiers())) { + throw new RuntimeException("Eval class must not be abstract"); + } + + Constructor constructor; + try { + constructor = evalClass.getDeclaredConstructor(OPERATION_CONSTRUCTOR_CLASS_ARRAY); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Missing constructor"); + } + if (!Modifier.isPublic(constructor.getModifiers())) { + throw new RuntimeException("Eval constructor must be public"); + } + m.put(ptgClass, constructor); + } + + /** + * returns the OperationEval concrete impl instance corresponding + * to the supplied operationPtg + */ + public static OperationEval create(OperationPtg ptg) { + if(ptg == null) { + throw new IllegalArgumentException("ptg must not be null"); + } + + Class ptgClass = ptg.getClass(); + + Constructor constructor = (Constructor) _constructorsByPtgClass.get(ptgClass); + if(constructor == null) { + if(ptgClass == ExpPtg.class) { + // ExpPtg is used for array formulas and shared formulas. + // it is currently unsupported, and may not even get implemented here + throw new RuntimeException("ExpPtg currently not supported"); + } + throw new RuntimeException("Unexpected operation ptg class (" + ptgClass.getName() + ")"); + } + + Object result; + Object[] initargs = { ptg }; + try { + result = constructor.newInstance(initargs); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + return (OperationEval) result; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java b/src/scratchpad/src/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java deleted file mode 100644 index a727d064b9..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/eventusermodel/MissingRecordAwareHSSFListener.java +++ /dev/null @@ -1,203 +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.eventusermodel; - -import org.apache.poi.hssf.eventusermodel.HSSFListener; -import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; -import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; -import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.BoolErrRecord; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.LabelRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.RKRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RowRecord; - -/** - *

    A HSSFListener which tracks rows and columns, and will - * trigger your HSSFListener for all rows and cells, - * even the ones that aren't actually stored in the file.

    - *

    This allows your code to have a more "Excel" like - * view of the data in the file, and not have to worry - * (as much) about if a particular row/cell is in the - * file, or was skipped from being written as it was - * blank. - */ -public class MissingRecordAwareHSSFListener implements HSSFListener { - private HSSFListener childListener; - private int lastSeenRow = -1; - private int lastSeenColumn = -1; - - /** - * Constructs a new MissingRecordAwareHSSFListener, which - * will fire processRecord on the supplied child - * HSSFListener for all Records, and missing records. - * @param listener The HSSFListener to pass records on to - */ - public MissingRecordAwareHSSFListener(HSSFListener listener) { - childListener = listener; - } - - public void processRecord(Record record) { - int thisRow = -1; - int thisColumn = -1; - - switch (record.getSid()) - { - // the BOFRecord can represent either the beginning of a sheet or the workbook - case BOFRecord.sid: - BOFRecord bof = (BOFRecord) record; - if (bof.getType() == bof.TYPE_WORKBOOK) - { - // Reset the row and column counts - new workbook - lastSeenRow = -1; - lastSeenColumn = -1; - //System.out.println("Encountered workbook"); - } else if (bof.getType() == bof.TYPE_WORKSHEET) - { - // Reset the row and column counts - new sheet - lastSeenRow = -1; - lastSeenColumn = -1; - //System.out.println("Encountered sheet reference"); - } - break; - case BoundSheetRecord.sid: - BoundSheetRecord bsr = (BoundSheetRecord) record; - //System.out.println("New sheet named: " + bsr.getSheetname()); - break; - case RowRecord.sid: - RowRecord rowrec = (RowRecord) record; - //System.out.println("Row " + rowrec.getRowNumber() + " found, first column at " - // + rowrec.getFirstCol() + " last column at " + rowrec.getLastCol()); - - // If there's a jump in rows, fire off missing row records - if(lastSeenRow+1 < rowrec.getRowNumber()) { - for(int i=(lastSeenRow+1); i - *

  • 1+TRUE = 2 - *
  • 1+FALSE = 1 - *
  • 1+"true" = #VALUE! - *
  • 1+"1" = 2 - *
  • 1+A1 = #VALUE if A1 contains "1" - *
  • 1+A1 = 2 if A1 contains ="1" - *
  • 1+A1 = 2 if A1 contains TRUE or =TRUE - *
  • 1+A1 = #VALUE! if A1 contains "TRUE" or ="TRUE" - */ -public class AddEval extends NumericOperationEval { - - private AddPtg delegate; - private static final ValueEvalToNumericXlator NUM_XLATOR = - new ValueEvalToNumericXlator((short) - ( ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - )); - - public AddEval(Ptg ptg) { - delegate = (AddPtg) ptg; - } - - public ValueEvalToNumericXlator getXlator() { - return NUM_XLATOR; - } - - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if(args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - - double d = 0; - for (int i = 0; i < 2; i++) { - ValueEval ve = singleOperandEvaluate(args[i], srcRow, srcCol); - if(ve instanceof ErrorEval) { - return ve; - } - if (ve instanceof NumericValueEval) { - d += ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - return ErrorEval.VALUE_INVALID; - } - } - if(Double.isNaN(d) || Double.isInfinite(d)) { - return ErrorEval.NUM_ERROR; - } - return new NumberEval(d); - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area2DEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area2DEval.java deleted file mode 100644 index 4b9a64c1c0..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area2DEval.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.eval; - -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Area2DEval implements AreaEval { -// TODO -refactor with Area3DEval - private final AreaPtg _delegate; - - private final ValueEval[] _values; - - public Area2DEval(Ptg ptg, ValueEval[] values) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - if(values == null) { - throw new IllegalArgumentException("values must not be null"); - } - for(int i=values.length-1; i>=0; i--) { - if(values[i] == null) { - throw new IllegalArgumentException("value array elements must not be null"); - } - } - // TODO - check size of array vs size of AreaPtg - _delegate = (AreaPtg) ptg; - _values = values; - } - - public int getFirstColumn() { - return _delegate.getFirstColumn(); - } - - public int getFirstRow() { - return _delegate.getFirstRow(); - } - - public int getLastColumn() { - return _delegate.getLastColumn(); - } - - public int getLastRow() { - return _delegate.getLastRow(); - } - - public ValueEval[] getValues() { - return _values; - } - - public ValueEval getValueAt(int row, int col) { - ValueEval retval; - int index = ((row-getFirstRow())*(getLastColumn()-getFirstColumn()+1))+(col-getFirstColumn()); - if (index <0 || index >= _values.length) - retval = ErrorEval.VALUE_INVALID; - else - retval = _values[index]; - return retval; - } - - public boolean contains(int row, int col) { - return (getFirstRow() <= row) && (getLastRow() >= row) - && (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean containsRow(int row) { - return (getFirstRow() <= row) && (getLastRow() >= row); - } - - public boolean containsColumn(short col) { - return (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean isColumn() { - return _delegate.getFirstColumn() == _delegate.getLastColumn(); - } - - public boolean isRow() { - return _delegate.getFirstRow() == _delegate.getLastRow(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area3DEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area3DEval.java deleted file mode 100644 index 2f539142d1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Area3DEval.java +++ /dev/null @@ -1,105 +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.Area3DPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Area3DEval implements AreaEval { - // TODO -refactor with Area3DEval - private final Area3DPtg _delegate; - - private final ValueEval[] _values; - - public Area3DEval(Ptg ptg, ValueEval[] values) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - if(values == null) { - throw new IllegalArgumentException("values must not be null"); - } - for(int i=values.length-1; i>=0; i--) { - if(values[i] == null) { - throw new IllegalArgumentException("value array elements must not be null"); - } - } - // TODO - check size of array vs size of AreaPtg - _values = values; - _delegate = (Area3DPtg) ptg; - } - - public int getFirstColumn() { - return _delegate.getFirstColumn(); - } - - public int getFirstRow() { - return _delegate.getFirstRow(); - } - - public int getLastColumn() { - return (short) _delegate.getLastColumn(); - } - - public int getLastRow() { - return _delegate.getLastRow(); - } - - public ValueEval[] getValues() { - return _values; - } - - public ValueEval getValueAt(int row, int col) { - ValueEval retval; - int index = (row-getFirstRow())*(col-getFirstColumn()); - if (index <0 || index >= _values.length) - retval = ErrorEval.VALUE_INVALID; - else - retval = _values[index]; - return retval; - } - - public boolean contains(int row, int col) { - return (getFirstRow() <= row) && (getLastRow() >= row) - && (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - public boolean containsRow(int row) { - return (getFirstRow() <= row) && (getLastRow() >= row); - } - - public boolean containsColumn(short col) { - return (getFirstColumn() <= col) && (getLastColumn() >= col); - } - - - public boolean isColumn() { - return _delegate.getFirstColumn() == _delegate.getLastColumn(); - } - - public boolean isRow() { - return _delegate.getFirstRow() == _delegate.getLastRow(); - } - - public int getExternSheetIndex() { - return _delegate.getExternSheetIndex(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/AreaEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/AreaEval.java deleted file mode 100644 index 82cc8a9b40..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/AreaEval.java +++ /dev/null @@ -1,105 +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 AreaEval extends ValueEval { - - /** - * returns the 0-based index of the first row in - * this area. - */ - public int getFirstRow(); - - /** - * returns the 0-based index of the last row in - * this area. - */ - public int getLastRow(); - - /** - * returns the 0-based index of the first col in - * this area. - */ - public int getFirstColumn(); - - /** - * returns the 0-based index of the last col in - * this area. - */ - public int getLastColumn(); - - /** - * returns true if the Area's start and end row indexes - * are same. This result of this method should agree - * with getFirstRow() == getLastRow(). - */ - public boolean isRow(); - - /** - * returns true if the Area's start and end col indexes - * are same. This result of this method should agree - * with getFirstColumn() == getLastColumn(). - */ - public boolean isColumn(); - - /** - * The array of values in this area. Although the area - * maybe 1D (ie. isRow() or isColumn() returns true) or 2D - * the returned array is 1D. - */ - public ValueEval[] getValues(); - - /** - * returns the ValueEval from the values array at the specified - * row and col index. The specified indexes should be absolute indexes - * in the sheet and not relative indexes within the area. Also, - * if contains(row, col) evaluates to true, a null value will - * bre returned. - * @param row - * @param col - */ - public ValueEval getValueAt(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 - */ - public boolean contains(int row, int col); - - /** - * returns true if the specified col is in range - * @param col - */ - public boolean containsColumn(short col); - - /** - * returns true if the specified row is in range - * @param row - */ - public boolean containsRow(int row); -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/BlankEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/BlankEval.java deleted file mode 100644 index df671821fe..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/BlankEval.java +++ /dev/null @@ -1,33 +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 9, 2005 - * - */ -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 class BlankEval implements ValueEval { - - public static BlankEval INSTANCE = new BlankEval(); - - private BlankEval() { - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/BoolEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/BoolEval.java deleted file mode 100644 index 7b625aaa98..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/BoolEval.java +++ /dev/null @@ -1,74 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.BoolPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public 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 a BoolEval instance representing b. - */ - public static final BoolEval valueOf(boolean b) { - // TODO - find / replace all occurrences - return b ? TRUE : FALSE; - } - - public BoolEval(Ptg ptg) { - this.value = ((BoolPtg) ptg).getValue(); - } - - private BoolEval(boolean value) { - this.value = value; - } - - public boolean getBooleanValue() { - return value; - } - - public double getNumberValue() { - return value ? 1 : 0; - } - - public String getStringValue() { - return value ? "TRUE" : "FALSE"; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(getStringValue()); - sb.append("]"); - return sb.toString(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ConcatEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ConcatEval.java deleted file mode 100644 index e54cd483f1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ConcatEval.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.ConcatPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class ConcatEval extends StringOperationEval { - - private ConcatPtg delegate; - - public ConcatEval(Ptg ptg) { - this.delegate = (ConcatPtg) ptg; - } - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if(args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < 2; i++) { - - ValueEval ve = singleOperandEvaluate(args[i], srcRow, srcCol); - if (ve instanceof StringValueEval) { - StringValueEval sve = (StringValueEval) ve; - sb.append(sve.getStringValue()); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { // must be an error eval - return ve; - } - } - - return new StringEval(sb.toString()); - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/DivideEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/DivideEval.java deleted file mode 100644 index 021168ad79..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/DivideEval.java +++ /dev/null @@ -1,95 +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.DividePtg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class DivideEval extends NumericOperationEval { - - private DividePtg delegate; - - private static final ValueEvalToNumericXlator NUM_XLATOR = - new ValueEvalToNumericXlator((short) - ( ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - )); - - public DivideEval(Ptg ptg) { - delegate = (DividePtg) ptg; - } - - protected ValueEvalToNumericXlator getXlator() { - return NUM_XLATOR; - } - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if(args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - Eval retval = null; - double d0 = 0; - double d1 = 0; - ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d0 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.VALUE_INVALID; - } - - if (retval == null) { // no error yet - ve = singleOperandEvaluate(args[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d1 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - - if (retval == null) { - retval = (d1 == 0) - ? ErrorEval.DIV_ZERO - : (Double.isNaN(d0) || Double.isNaN(d1)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : new NumberEval(d0 / d1); - } - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/EqualEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/EqualEval.java deleted file mode 100644 index e7b169294e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/EqualEval.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.EqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class EqualEval extends RelationalOperationEval { - - private EqualPtg delegate; - - public EqualEval(Ptg ptg) { - this.delegate = (EqualPtg) ptg; - } - - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result == 0) ? BoolEval.TRUE : BoolEval.FALSE; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ErrorEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ErrorEval.java deleted file mode 100644 index e8e197d201..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ErrorEval.java +++ /dev/null @@ -1,113 +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.usermodel.HSSFErrorConstants; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class ErrorEval implements ValueEval { - - // convenient access to namespace - private static final HSSFErrorConstants 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; - - public static final ErrorEval FUNCTION_NOT_IMPLEMENTED = new ErrorEval(FUNCTION_NOT_IMPLEMENTED_CODE); - // 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 HSSFErrorConstants.ERROR_NULL: return NULL_INTERSECTION; - case HSSFErrorConstants.ERROR_DIV_0: return DIV_ZERO; - case HSSFErrorConstants.ERROR_VALUE: return VALUE_INVALID; - case HSSFErrorConstants.ERROR_REF: return REF_INVALID; - case HSSFErrorConstants.ERROR_NAME: return NAME_INVALID; - case HSSFErrorConstants.ERROR_NUM: return NUM_ERROR; - case HSSFErrorConstants.ERROR_NA: return NA; - // non-std errors (conditions modeled as errors by POI) - case CIRCULAR_REF_ERROR_CODE: return CIRCULAR_REF_ERROR; - case FUNCTION_NOT_IMPLEMENTED_CODE: return FUNCTION_NOT_IMPLEMENTED; - } - 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(HSSFErrorConstants.isValidCode(errorCode)) { - return HSSFErrorConstants.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/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Eval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Eval.java deleted file mode 100644 index 086b765a30..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Eval.java +++ /dev/null @@ -1,29 +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 Eval { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/EvaluationException.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/EvaluationException.java deleted file mode 100755 index 7a23901b25..0000000000 --- a/src/scratchpad/src/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/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ExternalFunction.java deleted file mode 100755 index b1d81e6524..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ExternalFunction.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.eval; - -import org.apache.poi.hssf.record.formula.functions.FreeRefFunction; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -/** - * - * Common entry point for all external functions (where - * AbstractFunctionPtg.field_2_fnc_index == 255) - * - * @author Josh Micich - */ -final class ExternalFunction implements FreeRefFunction { - - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { - - int nIncomingArgs = args.length; - if(nIncomingArgs < 1) { - throw new RuntimeException("function name argument missing"); - } - - if (!(args[0] instanceof NameEval)) { - throw new RuntimeException("First argument should be a NameEval, but got (" - + args[0].getClass().getName() + ")"); - } - NameEval functionNameEval = (NameEval) args[0]; - - int nOutGoingArgs = nIncomingArgs -1; - Eval[] outGoingArgs = new Eval[nOutGoingArgs]; - System.arraycopy(args, 1, outGoingArgs, 0, nOutGoingArgs); - - FreeRefFunction targetFunc; - try { - targetFunc = findTargetFunction(workbook, functionNameEval); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - return targetFunc.evaluate(outGoingArgs, srcCellRow, srcCellCol, workbook, sheet); - } - - private FreeRefFunction findTargetFunction(HSSFWorkbook workbook, NameEval functionNameEval) throws EvaluationException { - - int numberOfNames = workbook.getNumberOfNames(); - - int nameIndex = functionNameEval.getIndex(); - if(nameIndex < 0 || nameIndex >= numberOfNames) { - throw new RuntimeException("Bad name index (" + nameIndex - + "). Allowed range is (0.." + (numberOfNames-1) + ")"); - } - - String functionName = workbook.getNameName(nameIndex); - if(false) { - System.out.println("received call to external function index (" + functionName + ")"); - } - // TODO - detect if the NameRecord corresponds to a named range, function, or something undefined - // throw the right errors in these cases - - // TODO find the implementation for the external function e.g. "YEARFRAC" or "ISEVEN" - - throw new EvaluationException(ErrorEval.FUNCTION_NOT_IMPLEMENTED); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FuncVarEval.java deleted file mode 100644 index 375d6b35da..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FuncVarEval.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. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.AbstractFunctionPtg; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.functions.Function; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class FuncVarEval extends FunctionEval { - - private AbstractFunctionPtg delegate; - - public FuncVarEval(Ptg funcPtg) { - delegate = (AbstractFunctionPtg) funcPtg; - } - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - Eval retval = null; - Function f = getFunction(); - if (f != null) - retval = f.evaluate(operands, srcRow, srcCol); - else - retval = ErrorEval.FUNCTION_NOT_IMPLEMENTED; - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } - - public short getFunctionIndex() { - return delegate.getFunctionIndex(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FunctionEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FunctionEval.java deleted file mode 100644 index 533c604a0c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/FunctionEval.java +++ /dev/null @@ -1,435 +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 java.util.HashMap; -import java.util.Map; - -import org.apache.poi.hssf.record.formula.functions.*; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class FunctionEval implements OperationEval { - /** - * Some function IDs that require special treatment - */ - private static final class FunctionID { - /** 78 */ - public static final int OFFSET = 78; - /** 148 */ - public static final int INDIRECT = 148; - /** 255 */ - public static final int EXTERNAL_FUNC = 255; - } - // convenient access to namespace - private static final FunctionID ID = null; - - protected static Function[] functions = produceFunctions(); - - private static Map freeRefFunctionsByIdMap; - - static { - Map m = new HashMap(); - addMapping(m, ID.OFFSET, new Offset()); - addMapping(m, ID.INDIRECT, new Indirect()); - addMapping(m, ID.EXTERNAL_FUNC, new ExternalFunction()); - freeRefFunctionsByIdMap = m; - } - private static void addMapping(Map m, int offset, FreeRefFunction frf) { - m.put(createFRFKey(offset), frf); - } - private static Integer createFRFKey(int functionIndex) { - return new Integer(functionIndex); - } - - - public Function getFunction() { - short fidx = getFunctionIndex(); - return functions[fidx]; - } - public boolean isFreeRefFunction() { - return freeRefFunctionsByIdMap.containsKey(createFRFKey(getFunctionIndex())); - } - public FreeRefFunction getFreeRefFunction() { - return (FreeRefFunction) freeRefFunctionsByIdMap.get(createFRFKey(getFunctionIndex())); - } - - public abstract short getFunctionIndex(); - - private static Function[] produceFunctions() { - Function[] retval = new Function[368]; - retval[0] = new Count(); // COUNT - retval[1] = new If(); // IF - retval[2] = new IsNa(); // ISNA - retval[3] = new IsError(); // ISERROR - retval[4] = new Sum(); // SUM - retval[5] = new Average(); // AVERAGE - retval[6] = new Min(); // MIN - retval[7] = new Max(); // MAX - retval[8] = new Row(); // ROW - retval[9] = new Column(); // COLUMN - retval[10] = new Na(); // NA - retval[11] = new Npv(); // NPV - retval[12] = new Stdev(); // STDEV - retval[13] = new Dollar(); // DOLLAR - retval[14] = new Fixed(); // FIXED - retval[15] = new Sin(); // SIN - retval[16] = new Cos(); // COS - retval[17] = new Tan(); // TAN - retval[18] = new Atan(); // ATAN - retval[19] = new Pi(); // PI - retval[20] = new Sqrt(); // SQRT - retval[21] = new Exp(); // EXP - retval[22] = new Ln(); // LN - retval[23] = new Log10(); // LOG10 - retval[24] = new Abs(); // ABS - retval[25] = new Int(); // INT - retval[26] = new Sign(); // SIGN - retval[27] = new Round(); // ROUND - retval[28] = new Lookup(); // LOOKUP - retval[29] = new Index(); // INDEX - retval[30] = new Rept(); // REPT - retval[31] = new Mid(); // MID - retval[32] = new Len(); // LEN - retval[33] = new Value(); // VALUE - retval[34] = new True(); // TRUE - retval[35] = new False(); // FALSE - retval[36] = new And(); // AND - retval[37] = new Or(); // OR - retval[38] = new Not(); // NOT - retval[39] = new Mod(); // MOD - retval[40] = new Dcount(); // DCOUNT - retval[41] = new Dsum(); // DSUM - retval[42] = new Daverage(); // DAVERAGE - retval[43] = new Dmin(); // DMIN - retval[44] = new Dmax(); // DMAX - retval[45] = new Dstdev(); // DSTDEV - retval[46] = new Var(); // VAR - retval[47] = new Dvar(); // DVAR - retval[48] = new Text(); // TEXT - retval[49] = new Linest(); // LINEST - retval[50] = new Trend(); // TREND - retval[51] = new Logest(); // LOGEST - retval[52] = new Growth(); // GROWTH - retval[53] = new Goto(); // GOTO - retval[54] = new Halt(); // HALT - retval[56] = new Pv(); // PV - retval[57] = new Fv(); // FV - retval[58] = new Nper(); // NPER - retval[59] = new Pmt(); // PMT - retval[60] = new Rate(); // RATE - retval[61] = new Mirr(); // MIRR - retval[62] = new Irr(); // IRR - retval[63] = new Rand(); // RAND - retval[64] = new Match(); // MATCH - retval[65] = new Date(); // DATE - retval[66] = new Time(); // TIME - retval[67] = new Day(); // DAY - retval[68] = new Month(); // MONTH - retval[69] = new Year(); // YEAR - retval[70] = new Weekday(); // WEEKDAY - retval[71] = new Hour(); // HOUR - retval[72] = new Minute(); // MINUTE - retval[73] = new Second(); // SECOND - retval[74] = new Now(); // NOW - retval[75] = new Areas(); // AREAS - retval[76] = new Rows(); // ROWS - retval[77] = new Columns(); // COLUMNS - retval[ID.OFFSET] = null; // Offset.evaluate has a different signature - retval[79] = new Absref(); // ABSREF - retval[80] = new Relref(); // RELREF - retval[81] = new Argument(); // ARGUMENT - retval[82] = new Search(); // SEARCH - retval[83] = new Transpose(); // TRANSPOSE - retval[84] = new org.apache.poi.hssf.record.formula.functions.Error(); // ERROR - retval[85] = new Step(); // STEP - retval[86] = new Type(); // TYPE - retval[87] = new Echo(); // ECHO - retval[88] = new Setname(); // SETNAME - retval[89] = new Caller(); // CALLER - retval[90] = new Deref(); // DEREF - retval[91] = new NotImplementedFunction(); // WINDOWS - retval[92] = new Series(); // SERIES - retval[93] = new NotImplementedFunction(); // DOCUMENTS - retval[94] = new Activecell(); // ACTIVECELL - retval[95] = new NotImplementedFunction(); // SELECTION - retval[96] = new Result(); // RESULT - retval[97] = new Atan2(); // ATAN2 - retval[98] = new Asin(); // ASIN - retval[99] = new Acos(); // ACOS - retval[100] = new Choose(); // CHOOSE - retval[101] = new Hlookup(); // HLOOKUP - retval[102] = new Vlookup(); // VLOOKUP - retval[103] = new Links(); // LINKS - retval[104] = new Input(); // INPUT - retval[105] = new Isref(); // ISREF - retval[106] = new NotImplementedFunction(); // GETFORMULA - retval[107] = new NotImplementedFunction(); // GETNAME - retval[108] = new Setvalue(); // SETVALUE - retval[109] = new Log(); // LOG - retval[110] = new Exec(); // EXEC - retval[111] = new Char(); // CHAR - retval[112] = new Lower(); // LOWER - retval[113] = new Upper(); // UPPER - retval[114] = new Proper(); // PROPER - retval[115] = new Left(); // LEFT - retval[116] = new Right(); // RIGHT - retval[117] = new Exact(); // EXACT - retval[118] = new Trim(); // TRIM - retval[119] = new Replace(); // REPLACE - retval[120] = new Substitute(); // SUBSTITUTE - retval[121] = new Code(); // CODE - retval[122] = new Names(); // NAMES - retval[123] = new NotImplementedFunction(); // DIRECTORY - retval[124] = new Find(); // FIND - retval[125] = new Cell(); // CELL - retval[126] = new Iserr(); // ISERR - retval[127] = new Istext(); // ISTEXT - retval[128] = new Isnumber(); // ISNUMBER - retval[129] = new Isblank(); // ISBLANK - retval[130] = new T(); // T - retval[131] = new N(); // N - retval[132] = new NotImplementedFunction(); // FOPEN - retval[133] = new NotImplementedFunction(); // FCLOSE - retval[134] = new NotImplementedFunction(); // FSIZE - retval[135] = new NotImplementedFunction(); // FREADLN - retval[136] = new NotImplementedFunction(); // FREAD - retval[137] = new NotImplementedFunction(); // FWRITELN - retval[138] = new NotImplementedFunction(); // FWRITE - retval[139] = new Fpos(); // FPOS - retval[140] = new Datevalue(); // DATEVALUE - retval[141] = new Timevalue(); // TIMEVALUE - retval[142] = new Sln(); // SLN - retval[143] = new Syd(); // SYD - retval[144] = new Ddb(); // DDB - retval[145] = new NotImplementedFunction(); // GETDEF - retval[146] = new Reftext(); // REFTEXT - retval[147] = new Textref(); // TEXTREF - retval[ID.INDIRECT] = null; // Indirect.evaluate has different signature - retval[149] = new NotImplementedFunction(); // REGISTER - retval[150] = new Call(); // CALL - retval[151] = new NotImplementedFunction(); // ADDBAR - retval[152] = new NotImplementedFunction(); // ADDMENU - retval[153] = new NotImplementedFunction(); // ADDCOMMAND - retval[154] = new NotImplementedFunction(); // ENABLECOMMAND - retval[155] = new NotImplementedFunction(); // CHECKCOMMAND - retval[156] = new NotImplementedFunction(); // RENAMECOMMAND - retval[157] = new NotImplementedFunction(); // SHOWBAR - retval[158] = new NotImplementedFunction(); // DELETEMENU - retval[159] = new NotImplementedFunction(); // DELETECOMMAND - retval[160] = new NotImplementedFunction(); // GETCHARTITEM - retval[161] = new NotImplementedFunction(); // DIALOGBOX - retval[162] = new Clean(); // CLEAN - retval[163] = new Mdeterm(); // MDETERM - retval[164] = new Minverse(); // MINVERSE - retval[165] = new Mmult(); // MMULT - retval[166] = new Files(); // FILES - retval[167] = new Ipmt(); // IPMT - retval[168] = new Ppmt(); // PPMT - retval[169] = new Counta(); // COUNTA - retval[170] = new NotImplementedFunction(); // CANCELKEY - retval[175] = new Initiate(); // INITIATE - retval[176] = new Request(); // REQUEST - retval[177] = new NotImplementedFunction(); // POKE - retval[178] = new NotImplementedFunction(); // EXECUTE - retval[179] = new NotImplementedFunction(); // TERMINATE - retval[180] = new NotImplementedFunction(); // RESTART - retval[181] = new Help(); // HELP - retval[182] = new NotImplementedFunction(); // GETBAR - retval[183] = new Product(); // PRODUCT - retval[184] = new Fact(); // FACT - retval[185] = new NotImplementedFunction(); // GETCELL - retval[186] = new NotImplementedFunction(); // GETWORKSPACE - retval[187] = new NotImplementedFunction(); // GETWINDOW - retval[188] = new NotImplementedFunction(); // GETDOCUMENT - retval[189] = new Dproduct(); // DPRODUCT - retval[190] = new Isnontext(); // ISNONTEXT - retval[191] = new NotImplementedFunction(); // GETNOTE - retval[192] = new Note(); // NOTE - retval[193] = new Stdevp(); // STDEVP - retval[194] = new Varp(); // VARP - retval[195] = new Dstdevp(); // DSTDEVP - retval[196] = new Dvarp(); // DVARP - retval[197] = new Trunc(); // TRUNC - retval[198] = new Islogical(); // ISLOGICAL - retval[199] = new Dcounta(); // DCOUNTA - retval[200] = new NotImplementedFunction(); // DELETEBAR - retval[201] = new NotImplementedFunction(); // UNREGISTER - retval[204] = new Usdollar(); // USDOLLAR - retval[205] = new Findb(); // FINDB - retval[206] = new Searchb(); // SEARCHB - retval[207] = new Replaceb(); // REPLACEB - retval[208] = new Leftb(); // LEFTB - retval[209] = new Rightb(); // RIGHTB - retval[210] = new Midb(); // MIDB - retval[211] = new Lenb(); // LENB - retval[212] = new Roundup(); // ROUNDUP - retval[213] = new Rounddown(); // ROUNDDOWN - retval[214] = new Asc(); // ASC - retval[215] = new Dbcs(); // DBCS - retval[216] = new Rank(); // RANK - retval[219] = new Address(); // ADDRESS - retval[220] = new Days360(); // DAYS360 - retval[221] = new Today(); // TODAY - retval[222] = new Vdb(); // VDB - retval[227] = new Median(); // MEDIAN - retval[228] = new Sumproduct(); // SUMPRODUCT - retval[229] = new Sinh(); // SINH - retval[230] = new Cosh(); // COSH - retval[231] = new Tanh(); // TANH - retval[232] = new Asinh(); // ASINH - retval[233] = new Acosh(); // ACOSH - retval[234] = new Atanh(); // ATANH - retval[235] = new Dget(); // DGET - retval[236] = new NotImplementedFunction(); // CREATEOBJECT - retval[237] = new Volatile(); // VOLATILE - retval[238] = new Lasterror(); // LASTERROR - retval[239] = new NotImplementedFunction(); // CUSTOMUNDO - retval[240] = new Customrepeat(); // CUSTOMREPEAT - retval[241] = new Formulaconvert(); // FORMULACONVERT - retval[242] = new NotImplementedFunction(); // GETLINKINFO - retval[243] = new NotImplementedFunction(); // TEXTBOX - retval[244] = new Info(); // INFO - retval[245] = new Group(); // GROUP - retval[246] = new NotImplementedFunction(); // GETOBJECT - retval[247] = new Db(); // DB - retval[248] = new NotImplementedFunction(); // PAUSE - retval[250] = new NotImplementedFunction(); // RESUME - retval[252] = new Frequency(); // FREQUENCY - retval[253] = new NotImplementedFunction(); // ADDTOOLBAR - retval[254] = new NotImplementedFunction(); // DELETETOOLBAR - retval[ID.EXTERNAL_FUNC] = null; // ExternalFunction is a FreeREfFunction - retval[256] = new NotImplementedFunction(); // RESETTOOLBAR - retval[257] = new Evaluate(); // EVALUATE - retval[258] = new NotImplementedFunction(); // GETTOOLBAR - retval[259] = new NotImplementedFunction(); // GETTOOL - retval[260] = new NotImplementedFunction(); // SPELLINGCHECK - retval[261] = new Errortype(); // ERRORTYPE - retval[262] = new NotImplementedFunction(); // APPTITLE - retval[263] = new NotImplementedFunction(); // WINDOWTITLE - retval[264] = new NotImplementedFunction(); // SAVETOOLBAR - retval[265] = new NotImplementedFunction(); // ENABLETOOL - retval[266] = new NotImplementedFunction(); // PRESSTOOL - retval[267] = new NotImplementedFunction(); // REGISTERID - retval[268] = new NotImplementedFunction(); // GETWORKBOOK - retval[269] = new Avedev(); // AVEDEV - retval[270] = new Betadist(); // BETADIST - retval[271] = new Gammaln(); // GAMMALN - retval[272] = new Betainv(); // BETAINV - retval[273] = new Binomdist(); // BINOMDIST - retval[274] = new Chidist(); // CHIDIST - retval[275] = new Chiinv(); // CHIINV - retval[276] = new Combin(); // COMBIN - retval[277] = new Confidence(); // CONFIDENCE - retval[278] = new Critbinom(); // CRITBINOM - retval[279] = new Even(); // EVEN - retval[280] = new Expondist(); // EXPONDIST - retval[281] = new Fdist(); // FDIST - retval[282] = new Finv(); // FINV - retval[283] = new Fisher(); // FISHER - retval[284] = new Fisherinv(); // FISHERINV - retval[285] = new Floor(); // FLOOR - retval[286] = new Gammadist(); // GAMMADIST - retval[287] = new Gammainv(); // GAMMAINV - retval[288] = new Ceiling(); // CEILING - retval[289] = new Hypgeomdist(); // HYPGEOMDIST - retval[290] = new Lognormdist(); // LOGNORMDIST - retval[291] = new Loginv(); // LOGINV - retval[292] = new Negbinomdist(); // NEGBINOMDIST - retval[293] = new Normdist(); // NORMDIST - retval[294] = new Normsdist(); // NORMSDIST - retval[295] = new Norminv(); // NORMINV - retval[296] = new Normsinv(); // NORMSINV - retval[297] = new Standardize(); // STANDARDIZE - retval[298] = new Odd(); // ODD - retval[299] = new Permut(); // PERMUT - retval[300] = new Poisson(); // POISSON - retval[301] = new Tdist(); // TDIST - retval[302] = new Weibull(); // WEIBULL - retval[303] = new Sumxmy2(); // SUMXMY2 - retval[304] = new Sumx2my2(); // SUMX2MY2 - retval[305] = new Sumx2py2(); // SUMX2PY2 - retval[306] = new Chitest(); // CHITEST - retval[307] = new Correl(); // CORREL - retval[308] = new Covar(); // COVAR - retval[309] = new Forecast(); // FORECAST - retval[310] = new Ftest(); // FTEST - retval[311] = new Intercept(); // INTERCEPT - retval[312] = new Pearson(); // PEARSON - retval[313] = new Rsq(); // RSQ - retval[314] = new Steyx(); // STEYX - retval[315] = new Slope(); // SLOPE - retval[316] = new Ttest(); // TTEST - retval[317] = new Prob(); // PROB - retval[318] = new Devsq(); // DEVSQ - retval[319] = new Geomean(); // GEOMEAN - retval[320] = new Harmean(); // HARMEAN - retval[321] = new Sumsq(); // SUMSQ - retval[322] = new Kurt(); // KURT - retval[323] = new Skew(); // SKEW - retval[324] = new Ztest(); // ZTEST - retval[325] = new Large(); // LARGE - retval[326] = new Small(); // SMALL - retval[327] = new Quartile(); // QUARTILE - retval[328] = new Percentile(); // PERCENTILE - retval[329] = new Percentrank(); // PERCENTRANK - retval[330] = new Mode(); // MODE - retval[331] = new Trimmean(); // TRIMMEAN - retval[332] = new Tinv(); // TINV - retval[334] = new NotImplementedFunction(); // MOVIECOMMAND - retval[335] = new NotImplementedFunction(); // GETMOVIE - retval[336] = new Concatenate(); // CONCATENATE - retval[337] = new Power(); // POWER - retval[338] = new NotImplementedFunction(); // PIVOTADDDATA - retval[339] = new NotImplementedFunction(); // GETPIVOTTABLE - retval[340] = new NotImplementedFunction(); // GETPIVOTFIELD - retval[341] = new NotImplementedFunction(); // GETPIVOTITEM - retval[342] = new Radians(); // RADIANS - retval[343] = new Degrees(); // DEGREES - retval[344] = new Subtotal(); // SUBTOTAL - retval[345] = new Sumif(); // SUMIF - retval[346] = new Countif(); // COUNTIF - retval[347] = new Countblank(); // COUNTBLANK - retval[348] = new NotImplementedFunction(); // SCENARIOGET - retval[349] = new NotImplementedFunction(); // OPTIONSLISTSGET - retval[350] = new Ispmt(); // ISPMT - retval[351] = new Datedif(); // DATEDIF - retval[352] = new Datestring(); // DATESTRING - retval[353] = new Numberstring(); // NUMBERSTRING - retval[354] = new Roman(); // ROMAN - retval[355] = new NotImplementedFunction(); // OPENDIALOG - retval[356] = new NotImplementedFunction(); // SAVEDIALOG - retval[357] = new NotImplementedFunction(); // VIEWGET - retval[358] = new NotImplementedFunction(); // GETPIVOTDATA - retval[359] = new Hyperlink(); // HYPERLINK - retval[360] = new NotImplementedFunction(); // PHONETIC - retval[361] = new Averagea(); // AVERAGEA - retval[362] = new Maxa(); // MAXA - retval[363] = new Mina(); // MINA - retval[364] = new Stdevpa(); // STDEVPA - retval[365] = new Varpa(); // VARPA - retval[366] = new Stdeva(); // STDEVA - retval[367] = new Vara(); // VARA - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java deleted file mode 100644 index 6a9a23217b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterEqualEval.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.GreaterEqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class GreaterEqualEval extends RelationalOperationEval { - - private GreaterEqualPtg delegate; - - public GreaterEqualEval(Ptg ptg) { - this.delegate = (GreaterEqualPtg) ptg; - } - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result >= 0) ? BoolEval.TRUE : BoolEval.FALSE; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java deleted file mode 100644 index 27da54a046..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/GreaterThanEval.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.GreaterThanPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class GreaterThanEval extends RelationalOperationEval { - - private GreaterThanPtg delegate; - - public GreaterThanEval(Ptg ptg) { - this.delegate = (GreaterThanPtg) ptg; - } - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result > 0) ? BoolEval.TRUE : BoolEval.FALSE;; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java deleted file mode 100644 index e45bf9e6bb..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessEqualEval.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.LessEqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class LessEqualEval extends RelationalOperationEval { - - private LessEqualPtg delegate; - - public LessEqualEval(Ptg ptg) { - this.delegate = (LessEqualPtg) ptg; - } - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result <= 0) ? BoolEval.TRUE : BoolEval.FALSE;; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessThanEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessThanEval.java deleted file mode 100644 index 1aac6f73bf..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/LessThanEval.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.LessThanPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class LessThanEval extends RelationalOperationEval { - - private LessThanPtg delegate; - - public LessThanEval(Ptg ptg) { - this.delegate = (LessThanPtg) ptg; - } - - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result < 0) ? BoolEval.TRUE : BoolEval.FALSE;; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java deleted file mode 100644 index 22d87b7e4d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/MultiplyEval.java +++ /dev/null @@ -1,89 +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.MultiplyPtg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class MultiplyEval extends NumericOperationEval { - - private MultiplyPtg delegate; - - private static final ValueEvalToNumericXlator NUM_XLATOR = - new ValueEvalToNumericXlator((short) - ( ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - )); - - public MultiplyEval(Ptg ptg) { - delegate = (MultiplyPtg) ptg; - } - - protected ValueEvalToNumericXlator getXlator() { - return NUM_XLATOR; - } - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if(args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - - double d0 = 0; - double d1 = 0; - ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d0 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - return ErrorEval.VALUE_INVALID; - } - - ve = singleOperandEvaluate(args[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d1 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - return ErrorEval.VALUE_INVALID; - } - - if (Double.isNaN(d0) || Double.isNaN(d1)) { - return ErrorEval.NUM_ERROR; - } - return new NumberEval(d0 * d1); - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NameEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NameEval.java deleted file mode 100755 index 682394b3c2..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NameEval.java +++ /dev/null @@ -1,48 +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 Eval { - - private final int _index; - - /** - * @param index zero based index to a defined name record - */ - public NameEval(int index) { - _index = index; - } - - /** - * @return zero based index to a defined name record - */ - public int getIndex() { - return _index; - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(_index); - sb.append("]"); - return sb.toString(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java deleted file mode 100644 index c5388f520f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NotEqualEval.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 8, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.NotEqualPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class NotEqualEval extends RelationalOperationEval { - - private NotEqualPtg delegate; - - public NotEqualEval(Ptg ptg) { - this.delegate = (NotEqualPtg) ptg; - } - - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - - RelationalValues rvs = super.doEvaluate(operands, srcRow, srcCol); - retval = rvs.ee; - int result = 0; - if (retval == null) { - result = doComparison(rvs.bs); - if (result == 0) { - result = doComparison(rvs.ss); - } - if (result == 0) { - result = doComparison(rvs.ds); - } - - retval = (result != 0) ? BoolEval.TRUE : BoolEval.FALSE; - } - - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumberEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumberEval.java deleted file mode 100644 index 44a017f631..0000000000 --- a/src/scratchpad/src/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; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class NumberEval implements NumericValueEval, StringValueEval { - - public static final NumberEval ZERO = new NumberEval(0); - - private double value; - private String stringValue; - - public NumberEval(Ptg ptg) { - if (ptg instanceof IntPtg) { - this.value = ((IntPtg) ptg).getValue(); - } - else if (ptg instanceof NumberPtg) { - this.value = ((NumberPtg) ptg).getValue(); - } - } - - public NumberEval(double value) { - this.value = value; - } - - public double getNumberValue() { - return value; - } - - public String getStringValue() { // TODO: limit to 15 decimal places - if (stringValue == null) - makeString(); - return stringValue; - } - - protected void makeString() { - if (!Double.isNaN(value)) { - long lvalue = Math.round(value); - if (lvalue == value) { - stringValue = String.valueOf(lvalue); - } - else { - stringValue = String.valueOf(value); - } - } - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java deleted file mode 100644 index 6bc1c95dc1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericOperationEval.java +++ /dev/null @@ -1,66 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 14, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class NumericOperationEval implements OperationEval { - - protected abstract ValueEvalToNumericXlator getXlator(); - - protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { - ValueEval retval; - if (eval instanceof AreaEval) { - AreaEval ae = (AreaEval) eval; - if (ae.contains(srcRow, srcCol)) { // circular ref! - retval = ErrorEval.CIRCULAR_REF_ERROR; - } - else if (ae.isRow()) { - if (ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - ve = getXlator().attemptXlateToNumeric(ve); - retval = getXlator().attemptXlateToNumeric(ve); - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - retval = getXlator().attemptXlateToNumeric(ve); - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else { - retval = getXlator().attemptXlateToNumeric((ValueEval) eval); - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/NumericValueEval.java deleted file mode 100644 index d5b92b8080..0000000000 --- a/src/scratchpad/src/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/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperandResolver.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperandResolver.java deleted file mode 100755 index be1cda5f8e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperandResolver.java +++ /dev/null @@ -1,277 +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; - -/** - * Provides functionality for evaluating arguments to functions and operators. - * - * @author Josh Micich - */ -public final class OperandResolver { - - 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(Eval arg, int srcCellRow, short srcCellCol) - throws EvaluationException { - Eval 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); - } - if (result instanceof ValueEval) { - return (ValueEval) result; - } - throw new RuntimeException("Unexpected eval type (" + result.getClass().getName() + ")"); - } - - /** - * 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. - * - * - * - * - * - * - * - *
      A  B  C  D 
    1152025 
    2   200
    3   300
    3   400
    - * - * 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 
    1152025 
    212151220#VALUE!200
    313151320#VALUE!300
    4#VALUE!#VALUE!#VALUE!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 ErrorEval.CIRCULAR_REF_ERROR upon entry to this method. It - * is assumed logic exists elsewhere to produce this behaviour. - * - * @return whatever the selected cell's evaluated value is. Never 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, short srcCellCol) throws EvaluationException { - ValueEval result = chooseSingleElementFromAreaInternal(ae, srcCellRow, srcCellCol); - if(result == null) { - // This seems to be required because AreaEval.values() array may contain nulls. - // perhaps that should not be allowed. - result = BlankEval.INSTANCE; - } - if (result instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) result); - - } - return result; - } - - /** - * @return possibly ErrorEval, and null - */ - private static ValueEval chooseSingleElementFromAreaInternal(AreaEval ae, - int srcCellRow, short 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 HSSFFormulaEvaluator). - */ - } - - if (ae.isColumn()) { - if(ae.isRow()) { - return ae.getValues()[0]; - } - if(!ae.containsRow(srcCellRow)) { - throw EvaluationException.invalidValue(); - } - return ae.getValueAt(srcCellRow, ae.getFirstColumn()); - } - if(!ae.isRow()) { - // multi-column, multi-row area - if(ae.containsRow(srcCellRow) && ae.containsColumn(srcCellCol)) { - return ae.getValueAt(ae.getFirstRow(), ae.getFirstColumn()); - } - throw EvaluationException.invalidValue(); - } - if(!ae.containsColumn(srcCellCol)) { - throw EvaluationException.invalidValue(); - } - return ae.getValueAt(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() ).

    - * - * 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 { - 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 not supported and must be handled by the caller. - * @param ev must be a NumberEval, StringEval or BoolEval - * @return actual, parsed or interpreted double value (respectively). - * @throws EvaluationException(#VALUE!) only if a StringEval is supplied and cannot be parsed - * as a double (See parseDouble() for allowable formats). - * @throws RuntimeException if the supplied parameter is not NumberEval, - * StringEval or BoolEval - */ - public static double coerceValueToDouble(ValueEval ev) throws EvaluationException { - - 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 currency prefixes, commas, leading and trailing spaces.

    - * - * Some examples:
    - * " 123 " -> 123.0
    - * ".123" -> 0.123
    - * These not supported yet:
    - * " $ 1,000.00 " -> 1000.0
    - * "$1.25E4" -> 12500.0
    - * "5**2" -> 500
    - * "250%" -> 2.5
    - * - * @param text - * @return null if the specified text cannot be parsed as a number - */ - public static Double parseDouble(String pText) { - String text = pText.trim(); - if(text.length() < 1) { - return null; - } - boolean isPositive = true; - if(text.charAt(0) == '-') { - isPositive = false; - text= text.substring(1).trim(); - } - - if(!Character.isDigit(text.charAt(0))) { - // avoid using NumberFormatException to tell when string is not a number - return null; - } - // TODO - support notation like '1E3' (==1000) - - double val; - try { - val = Double.parseDouble(text); - } catch (NumberFormatException e) { - return null; - } - return new Double(isPositive ? +val : -val); - } - - /** - * @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 instanceof NumberEval) { - NumberEval neval = (NumberEval) ve; - return neval.getStringValue(); - } - - if (ve instanceof BlankEval) { - return ""; - } - throw new IllegalArgumentException("Unexpected eval class (" + ve.getClass().getName() + ")"); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperationEval.java deleted file mode 100644 index aefd5aefad..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/OperationEval.java +++ /dev/null @@ -1,53 +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 OperationEval extends Eval { - - /* - * Read this, this will make your work easier when coding - * an "evaluate()" - * - * Things to note when implementing evaluate(): - * 1. Check the length of operands - * (use "switch(operands[x])" if possible) - * - * 2. The possible Evals that you can get as args to evaluate are one of: - * NumericValueEval, StringValueEval, RefEval, AreaEval - * 3. If it is RefEval, the innerValueEval could be one of: - * NumericValueEval, StringValueEval, BlankEval - * 4. If it is AreaEval, each of the values could be one of: - * NumericValueEval, StringValueEval, BlankEval, RefEval - * - * 5. For numeric functions/operations, keep the result in double - * till the end and before returning a new NumberEval, check to see - * if the double is a NaN - if NaN, return ErrorEval.ERROR_503 - */ - public abstract Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol); - - public abstract int getNumberOfOperands(); - - public abstract int getType(); -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PercentEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PercentEval.java deleted file mode 100755 index c698a4e502..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PercentEval.java +++ /dev/null @@ -1,71 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.PercentPtg; -import org.apache.poi.hssf.record.formula.Ptg; - -/** - * Implementation of Excel formula token '%'.

    - * @author Josh Micich - */ -public final class PercentEval extends NumericOperationEval { - - private PercentPtg _delegate; - - private static final ValueEvalToNumericXlator NUM_XLATOR = new ValueEvalToNumericXlator( - (short) (ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED | ValueEvalToNumericXlator.REF_STRING_IS_PARSED)); - - public PercentEval(Ptg ptg) { - _delegate = (PercentPtg) ptg; - } - - protected ValueEvalToNumericXlator getXlator() { - return NUM_XLATOR; - } - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if (args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - - ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - double d0 = ((NumericValueEval) ve).getNumberValue(); - return new NumberEval(d0 / 100); - } - - if (ve instanceof BlankEval) { - return NumberEval.ZERO; - } - if (ve instanceof ErrorEval) { - return ve; - } - return ErrorEval.VALUE_INVALID; - } - - public int getNumberOfOperands() { - return _delegate.getNumberOfOperands(); - } - - public int getType() { - return _delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PowerEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PowerEval.java deleted file mode 100644 index 651c5d2aa2..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/PowerEval.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.eval; - -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.PowerPtg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class PowerEval extends NumericOperationEval { - - private PowerPtg delegate; - - private static final ValueEvalToNumericXlator NUM_XLATOR = - new ValueEvalToNumericXlator((short) - ( ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - )); - - public PowerEval(Ptg ptg) { - delegate = (PowerPtg) ptg; - } - - protected ValueEvalToNumericXlator getXlator() { - return NUM_XLATOR; - } - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if(args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - double d0 = 0; - double d1 = 0; - - ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d0 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - return ErrorEval.VALUE_INVALID; - } - - ve = singleOperandEvaluate(args[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d1 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - return ErrorEval.VALUE_INVALID; - } - - double p = Math.pow(d0, d1); - if (Double.isNaN(p)) { - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(p); - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java deleted file mode 100644 index 898d7a8618..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref2DEval.java +++ /dev/null @@ -1,50 +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.ReferencePtg; - -/** - * @author adeshmukh - * - */ -public final class Ref2DEval implements RefEval { - - private final ValueEval value; - private final ReferencePtg delegate; - - public Ref2DEval(ReferencePtg ptg, ValueEval ve) { - if(ve == null) { - throw new IllegalArgumentException("ve must not be null"); - } - if(false && ptg == null) { // TODO - fix dodgy code in MultiOperandNumericFunction - throw new IllegalArgumentException("ptg must not be null"); - } - value = ve; - delegate = ptg; - } - public ValueEval getInnerValueEval() { - return value; - } - public int getRow() { - return delegate.getRow(); - } - public int getColumn() { - return delegate.getColumn(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java deleted file mode 100644 index 622d686329..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/Ref3DEval.java +++ /dev/null @@ -1,53 +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.Ref3DPtg; - -/** - * @author Amol S. Deshmukh - * - */ -public final class Ref3DEval implements RefEval { - - private final ValueEval value; - private final Ref3DPtg delegate; - - public Ref3DEval(Ref3DPtg ptg, ValueEval ve) { - if(ve == null) { - throw new IllegalArgumentException("ve must not be null"); - } - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - value = ve; - delegate = ptg; - } - public ValueEval getInnerValueEval() { - return value; - } - public int getRow() { - return delegate.getRow(); - } - public int getColumn() { - return delegate.getColumn(); - } - public int getExternSheetIndex() { - return delegate.getExternSheetIndex(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RefEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RefEval.java deleted file mode 100644 index e462586d72..0000000000 --- a/src/scratchpad/src/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 HSSFCell 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 { - - /** - * The (possibly evaluated) ValueEval contained - * in this RefEval. eg. if cell A1 contains "test" - * then in a formula referring to cell A1 - * the RefEval representing - * A1 will return as the getInnerValueEval() the - * object of concrete type StringEval - */ - public ValueEval getInnerValueEval(); - - /** - * returns the zero based column index. - */ - public int getColumn(); - - /** - * returns the zero based row index. - */ - public int getRow(); -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java deleted file mode 100644 index 9b1a2ece4f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/RelationalOperationEval.java +++ /dev/null @@ -1,216 +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 10, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class RelationalOperationEval implements OperationEval { - - protected class RelationalValues { - public Double[] ds = new Double[2]; - public Boolean[] bs = new Boolean[2]; - public String[] ss = new String[3]; - public ErrorEval ee = null; - } - - - /* - * 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 > any number. ALWAYS - * Bool > any string. ALWAYS - * Bool.TRUE > Bool.FALSE - * - * String > any number. ALWAYS - * String > Blank. ALWAYS - * String are sorted dictionary wise - * - * Blank == 0 (numeric) - */ - public RelationalValues doEvaluate(Eval[] operands, int srcRow, short srcCol) { - RelationalValues retval = new RelationalValues(); - - switch (operands.length) { - default: - retval.ee = ErrorEval.VALUE_INVALID; - break; - case 2: - internalDoEvaluate(operands, srcRow, srcCol, retval, 0); - internalDoEvaluate(operands, srcRow, srcCol, retval, 1); - } // end switch - return retval; - } - - /** - * convenience method to avoid code duplication for multiple operands - * @param operands - * @param srcRow - * @param srcCol - * @param retval - * @param index - */ - private void internalDoEvaluate(Eval[] operands, int srcRow, short srcCol, RelationalValues retval, int index) { - if (operands[index] instanceof BoolEval) { - BoolEval be = (BoolEval) operands[index]; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (operands[index] instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) operands[index]; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (operands[index] instanceof StringValueEval) { - StringValueEval se = (StringValueEval) operands[index]; - retval.ss[index] = se.getStringValue(); - } - else if (operands[index] instanceof RefEval) { - RefEval re = (RefEval) operands[index]; - ValueEval ve = re.getInnerValueEval(); - if (ve instanceof BoolEval) { - BoolEval be = (BoolEval) ve; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (ve instanceof BlankEval) { - retval.ds[index] = new Double(0); - } - else if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (ve instanceof StringValueEval) { - StringValueEval se = (StringValueEval) ve; - retval.ss[index] = se.getStringValue(); - } - } - else if (operands[index] instanceof AreaEval) { - AreaEval ae = (AreaEval) operands[index]; - if (ae.isRow()) { - if (ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - if (ve instanceof BoolEval) { - BoolEval be = (BoolEval) ve; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (ve instanceof BlankEval) { - retval.ds[index] = new Double(0); - } - else if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (ve instanceof StringValueEval) { - StringValueEval se = (StringValueEval) ve; - retval.ss[index] = se.getStringValue(); - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - if (ve instanceof BoolEval) { - BoolEval be = (BoolEval) ve; - retval.bs[index] = Boolean.valueOf(be.getBooleanValue()); - } - else if (ve instanceof BlankEval) { - retval.ds[index] = new Double(0); - } - else if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - retval.ds[index] = new Double(ne.getNumberValue()); - } - else if (ve instanceof StringValueEval) { - StringValueEval se = (StringValueEval) ve; - retval.ss[index] = se.getStringValue(); - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - else { - retval.ee = ErrorEval.VALUE_INVALID; - } - } - } - - // if both null return 0, else non null wins, else TRUE wins - protected int doComparison(Boolean[] bs) { - int retval = 0; - if (bs[0] != null || bs[1] != null) { - retval = bs[0] != null - ? bs[1] != null - ? bs[0].booleanValue() - ? bs[1].booleanValue() - ? 0 - : 1 - : bs[1].booleanValue() - ? -1 - : 0 - : 1 - : bs[1] != null - ? -1 - : 0; - } - return retval; - } - - // if both null return 0, else non null wins, else string compare - protected int doComparison(String[] ss) { - int retval = 0; - if (ss[0] != null || ss[1] != null) { - retval = ss[0] != null - ? ss[1] != null - ? ss[0].compareTo(ss[1]) - : 1 - : ss[1] != null - ? -1 - : 0; - } - return retval; - } - - // if both null return 0, else non null wins, else doublevalue compare - protected int doComparison(Double[] ds) { - int retval = 0; - if (ds[0] != null || ds[1] != null) { - retval = ds[0] != null - ? ds[1] != null - ? ds[0].compareTo(ds[1]) - : 1 - : ds[1] != null - ? -1 - : 0; - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringEval.java deleted file mode 100644 index 27a9c6a627..0000000000 --- a/src/scratchpad/src/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"); - } - this.value = value; - } - - public String getStringValue() { - return value; - } - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(value); - sb.append("]"); - return sb.toString(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringOperationEval.java deleted file mode 100644 index e2a3c72a4c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringOperationEval.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. -*/ -/* - * Created on May 14, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class StringOperationEval implements OperationEval { - - - - /** - * Returns an instanceof StringValueEval or ErrorEval or BlankEval - * - * @param eval - * @param srcRow - * @param srcCol - */ - protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { - ValueEval retval; - if (eval instanceof AreaEval) { - AreaEval ae = (AreaEval) eval; - if (ae.contains(srcRow, srcCol)) { // circular ref! - retval = ErrorEval.CIRCULAR_REF_ERROR; - } - else if (ae.isRow()) { - if (ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - retval = internalResolveEval(eval); - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - retval = internalResolveEval(eval); - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else { - retval = internalResolveEval(eval); - } - return retval; - } - - private ValueEval internalResolveEval(Eval eval) { - ValueEval retval; - if (eval instanceof StringValueEval) { - retval = (StringValueEval) eval; - } - else if (eval instanceof RefEval) { - RefEval re = (RefEval) eval; - ValueEval tve = re.getInnerValueEval(); - if (tve instanceof StringValueEval || tve instanceof BlankEval) { - retval = tve; - } - else { - retval = ErrorEval.NAME_INVALID; - } - } - else if (eval instanceof BlankEval) { - retval = (BlankEval) eval; - } - else { - retval = ErrorEval.NAME_INVALID; - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringValueEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/StringValueEval.java deleted file mode 100644 index 46c12236b9..0000000000 --- a/src/scratchpad/src/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/scratchpad/src/org/apache/poi/hssf/record/formula/eval/SubtractEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/SubtractEval.java deleted file mode 100644 index 85a3845299..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/SubtractEval.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.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.SubtractPtg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class SubtractEval extends NumericOperationEval { - - private SubtractPtg delegate; - - private static final ValueEvalToNumericXlator NUM_XLATOR = - new ValueEvalToNumericXlator((short) - ( ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - )); - - public SubtractEval(Ptg ptg) { - delegate = (SubtractPtg) ptg; - } - - protected ValueEvalToNumericXlator getXlator() { - return NUM_XLATOR; - } - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if(args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - Eval retval = null; - double d0 = 0; - double d1 = 0; - ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d0 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.VALUE_INVALID; - } - - if (retval == null) { // no error yet - ve = singleOperandEvaluate(args[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d1 = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - - if (retval == null) { - retval = (Double.isNaN(d0) || Double.isNaN(d1)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : new NumberEval(d0 - d1); - } - return retval; - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.java deleted file mode 100644 index ef6f533ea5..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryMinusEval.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.Ptg; -import org.apache.poi.hssf.record.formula.UnaryMinusPtg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class UnaryMinusEval extends NumericOperationEval { - - private UnaryMinusPtg delegate; - private static final ValueEvalToNumericXlator NUM_XLATOR = - new ValueEvalToNumericXlator((short) - ( ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - )); - - - public UnaryMinusEval(Ptg ptg) { - this.delegate = (UnaryMinusPtg) ptg; - } - - protected ValueEvalToNumericXlator getXlator() { - return NUM_XLATOR; - } - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - if(args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - double d = 0; - - ValueEval ve = singleOperandEvaluate(args[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - d = ((NumericValueEval) ve).getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else if (ve instanceof ErrorEval) { - return ve; - } - - return new NumberEval(-d); - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java deleted file mode 100644 index edcc7bee79..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/UnaryPlusEval.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.poi.hssf.record.formula.eval; - -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.UnaryPlusPtg; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class UnaryPlusEval implements OperationEval { - - private UnaryPlusPtg delegate; - - /** - * called by reflection - */ - public UnaryPlusEval(Ptg ptg) { - this.delegate = (UnaryPlusPtg) ptg; - } - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - if(args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - double d; - try { - ValueEval ve = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - if(ve instanceof BlankEval) { - return NumberEval.ZERO; - } - if(ve instanceof StringEval) { - // Note - asymmetric with UnaryMinus - // -"hello" evaluates to #VALUE! - // but +"hello" evaluates to "hello" - return ve; - } - d = OperandResolver.coerceValueToDouble(ve); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - return new NumberEval(+d); - } - - public int getNumberOfOperands() { - return delegate.getNumberOfOperands(); - } - - public int getType() { - return delegate.getType(); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEval.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEval.java deleted file mode 100644 index 4581fa4d6e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEval.java +++ /dev/null @@ -1,29 +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 ValueEval extends Eval { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java deleted file mode 100644 index 1abcf34d2b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/eval/ValueEvalToNumericXlator.java +++ /dev/null @@ -1,188 +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 14, 2005 - * - */ -package org.apache.poi.hssf.record.formula.eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class ValueEvalToNumericXlator { - - public static final int STRING_IS_PARSED = 0x0001; - public static final int BOOL_IS_PARSED = 0x0002; - public static final int BLANK_IS_PARSED = 0x0004; // => blanks are not ignored, converted to 0 - - public static final int REF_STRING_IS_PARSED = 0x0008; - public static final int REF_BOOL_IS_PARSED = 0x0010; - public static final int REF_BLANK_IS_PARSED = 0x0020; - - public static final int STRING_IS_INVALID_VALUE = 0x0800; - - private final int flags; - - - public ValueEvalToNumericXlator(int flags) { - - if (false) { // uncomment to see who is using this class - System.err.println(new Throwable().getStackTrace()[1].getClassName() + "\t0x" - + Integer.toHexString(flags).toUpperCase()); - } - this.flags = flags; - } - - /** - * returned value can be either A NumericValueEval, BlankEval or ErrorEval. - * The params can be either NumberEval, BoolEval, StringEval, or - * RefEval - * @param eval - */ - public ValueEval attemptXlateToNumeric(ValueEval eval) { - ValueEval retval = null; - - if (eval == null) { - retval = BlankEval.INSTANCE; - } - - // most common case - least worries :) - else if (eval instanceof NumberEval) { - retval = eval; - } - - // booleval - else if (eval instanceof BoolEval) { - retval = ((flags & BOOL_IS_PARSED) > 0) - ? (NumericValueEval) eval - : xlateBlankEval(BLANK_IS_PARSED); - } - - // stringeval - else if (eval instanceof StringEval) { - retval = xlateStringEval((StringEval) eval); // TODO: recursive call needed - } - - // refeval - else if (eval instanceof RefEval) { - retval = xlateRefEval((RefEval) eval); - } - - // erroreval - else if (eval instanceof ErrorEval) { - retval = eval; - } - - else if (eval instanceof BlankEval) { - retval = xlateBlankEval(BLANK_IS_PARSED); - } - - // probably AreaEval? then not acceptable. - else { - throw new RuntimeException("Invalid ValueEval type passed for conversion: " + eval.getClass()); - } - - return retval; - } - - /** - * no args are required since BlankEval has only one - * instance. If flag is set, a zero - * valued numbereval is returned, else BlankEval.INSTANCE - * is returned. - */ - private ValueEval xlateBlankEval(int flag) { - return ((flags & flag) > 0) - ? (ValueEval) NumberEval.ZERO - : BlankEval.INSTANCE; - } - - /** - * uses the relevant flags to decode the supplied RefVal - * @param eval - */ - private ValueEval xlateRefEval(RefEval reval) { - ValueEval eval = reval.getInnerValueEval(); - - // most common case - least worries :) - if (eval instanceof NumberEval) { - return eval; - } - - if (eval instanceof BoolEval) { - return ((flags & REF_BOOL_IS_PARSED) > 0) - ? (ValueEval) eval - : BlankEval.INSTANCE; - } - - if (eval instanceof StringEval) { - return xlateRefStringEval((StringEval) eval); - } - - if (eval instanceof ErrorEval) { - return eval; - } - - if (eval instanceof BlankEval) { - return xlateBlankEval(REF_BLANK_IS_PARSED); - } - - throw new RuntimeException("Invalid ValueEval type passed for conversion: (" - + eval.getClass().getName() + ")"); - } - - /** - * uses the relevant flags to decode the StringEval - * @param eval - */ - private ValueEval xlateStringEval(StringEval eval) { - - if ((flags & STRING_IS_PARSED) > 0) { - String s = eval.getStringValue(); - Double d = OperandResolver.parseDouble(s); - if(d == null) { - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(d.doubleValue()); - } - // strings are errors? - if ((flags & STRING_IS_INVALID_VALUE) > 0) { - return ErrorEval.VALUE_INVALID; - } - - // ignore strings - return xlateBlankEval(BLANK_IS_PARSED); - } - - /** - * uses the relevant flags to decode the StringEval - * @param eval - */ - private ValueEval xlateRefStringEval(StringEval sve) { - if ((flags & REF_STRING_IS_PARSED) > 0) { - String s = sve.getStringValue(); - Double d = OperandResolver.parseDouble(s); - if(d == null) { - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(d.doubleValue()); - } - // strings are blanks - return BlankEval.INSTANCE; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Abs.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Abs.java deleted file mode 100644 index 1bebb358bb..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Abs.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Abs extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.abs(d); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Absref.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Absref.java deleted file mode 100644 index 3a6e94a66e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Absref.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Absref extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acos.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acos.java deleted file mode 100644 index bc5b5720ee..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acos.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Acos extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.acos(d); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acosh.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acosh.java deleted file mode 100644 index 794516e57f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Acosh.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * Support for hyperbolic trig functions was added as a part of - * Java distribution only in JDK1.5. This class uses custom - * naive implementation based on formulas at: - * http://www.math2.org/math/trig/hyperbolics.htm - * These formulas seem to agree with excel's implementation. - * - */ -public class Acosh extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - } - - if (retval == null) { - d = MathX.acosh(d); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Activecell.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Activecell.java deleted file mode 100644 index 17b04137af..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Activecell.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Activecell extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Address.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Address.java deleted file mode 100644 index 9b408e0d34..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Address.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Address extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/And.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/And.java deleted file mode 100644 index 455772f737..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/And.java +++ /dev/null @@ -1,85 +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 9, 2005 - * - */ -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.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class And extends BooleanFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - boolean b = true; - boolean atleastOneNonBlank = false; - - /* - * Note: do not abort the loop if b is false, since we could be - * dealing with errorevals later. - */ - outer: - for (int i=0, iSize=operands.length; i - *

  • Blanks are not either true or false - *
  • Strings are not either true or false (even strings "true" - * or "TRUE" or "0" etc.) - *
  • Numbers: 0 is false. Any other number is TRUE. - *
  • References are evaluated and above rules apply. - *
  • Areas: Individual cells in area are evaluated and checked to - * see if they are blanks, strings etc. - * - */ -public abstract class BooleanFunction implements Function { - - protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol, boolean stringsAreBlanks) { - ValueEval retval; - - if (eval instanceof RefEval) { - RefEval re = (RefEval) eval; - ValueEval ve = re.getInnerValueEval(); - retval = internalResolve(ve, true); - } - else { - retval = internalResolve(eval, stringsAreBlanks); - } - - return retval; - } - - private ValueEval internalResolve(Eval ve, boolean stringsAreBlanks) { - ValueEval retval = null; - - // blankeval is returned as is - if (ve instanceof BlankEval) { - retval = BlankEval.INSTANCE; - } - - // stringeval - else if (ve instanceof StringEval) { - retval = stringsAreBlanks ? (ValueEval) BlankEval.INSTANCE : (StringEval) ve; - } - - // bools are bools :) - else if (ve instanceof BoolEval) { - retval = (BoolEval) ve; - } - - // convert numbers to bool - else if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - double d = ne.getNumberValue(); - retval = Double.isNaN(d) - ? (ValueEval) ErrorEval.VALUE_INVALID - : (d != 0) - ? BoolEval.TRUE - : BoolEval.FALSE; - } - - // since refevals - else { - retval = ErrorEval.VALUE_INVALID; - } - - return retval; - - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Call.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Call.java deleted file mode 100644 index a1cb4ca376..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Call.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Call extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Caller.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Caller.java deleted file mode 100644 index 206d08a703..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Caller.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Caller extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ceiling.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ceiling.java deleted file mode 100644 index a158b856bc..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ceiling.java +++ /dev/null @@ -1,82 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Ceiling extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d0 = 0; - double d1 = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d0 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - if (retval == null) { - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d1 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - double d = MathX.ceiling(d0, d1); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Cell.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Cell.java deleted file mode 100644 index ffbd322395..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Cell.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Cell extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Char.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Char.java deleted file mode 100644 index 2c4271dc70..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Char.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Char extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chidist.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chidist.java deleted file mode 100644 index b431fe361a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chidist.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Chidist extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chiinv.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chiinv.java deleted file mode 100644 index c2d45b0e6e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chiinv.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Chiinv extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chitest.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chitest.java deleted file mode 100644 index b7065b0ea6..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Chitest.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Chitest extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Choose.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Choose.java deleted file mode 100644 index e7acc93c48..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Choose.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Choose extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Clean.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Clean.java deleted file mode 100644 index cc01655d57..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Clean.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Clean extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Code.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Code.java deleted file mode 100644 index e340a5757d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Code.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Code extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Column.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Column.java deleted file mode 100644 index adde35c162..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Column.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -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.Eval; -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; - -public class Column implements Function { - public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - int cnum = -1; - - switch (evals.length) { - default: - retval = ErrorEval.VALUE_INVALID; - case 1: - if (evals[0] instanceof AreaEval) { - AreaEval ae = (AreaEval) evals[0]; - cnum = ae.getFirstColumn(); - } - else if (evals[0] instanceof RefEval) { - RefEval re = (RefEval) evals[0]; - cnum = re.getColumn(); - } - else { // anything else is not valid argument - retval = ErrorEval.VALUE_INVALID; - } - break; - case 0: - cnum = srcCellCol; - } - - if (retval == null) { - retval = (cnum >= 0) - ? new NumberEval(cnum + 1) // +1 since excel colnums are 1 based - : (ValueEval) ErrorEval.VALUE_INVALID; - } - - return retval; - } - - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Columns.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Columns.java deleted file mode 100644 index b75864e72d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Columns.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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; - -/** - * Implementation for Excel COLUMNS function. - * - * @author Josh Micich - */ -public final class Columns implements Function { - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - switch(args.length) { - case 1: - // expected - break; - case 0: - // too few arguments - return ErrorEval.VALUE_INVALID; - default: - // too many arguments - return ErrorEval.VALUE_INVALID; - } - Eval firstArg = args[0]; - - int result; - if (firstArg instanceof AreaEval) { - AreaEval ae = (AreaEval) firstArg; - result = ae.getLastColumn() - ae.getFirstColumn() + 1; - } else if (firstArg instanceof RefEval) { - result = 1; - } else { // anything else is not valid argument - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(result); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Combin.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Combin.java deleted file mode 100644 index 72d6d4691e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Combin.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Combin extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d0 = 0; - double d1 = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d0 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - if (retval == null) { - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d1 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - if (d0 > Integer.MAX_VALUE || d1 > Integer.MAX_VALUE) { - retval = ErrorEval.NUM_ERROR; - } - else { - double d = MathX.nChooseK((int) d0, (int) d1); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Concatenate.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Concatenate.java deleted file mode 100644 index be961c151e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Concatenate.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.StringValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Concatenate extends TextFunction { - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - StringBuffer sb = new StringBuffer(); - - for (int i=0, iSize=operands.length; i 30) { - // too many arguments - return ErrorEval.VALUE_INVALID; - } - - int temp = 0; - // Note - observed behavior of Excel: - // Error values like #VALUE!, #REF!, #DIV/0!, #NAME? etc don't cause this COUNTA to return an error - // in fact, they seem to get counted - - for(int i=0; i - * - * Syntax: COUNTIF ( range, criteria ) - * - * - * - *
    range   is the range of cells to be counted based on the criteria
    criteriais used to determine which cells to count
    - *

    - * - * @author Josh Micich - */ -public final class Countif implements Function { - - /** - * Common interface for the matching criteria. - */ - private interface I_MatchPredicate { - boolean matches(Eval x); - } - - private static final class NumberMatcher implements I_MatchPredicate { - - private final double _value; - - public NumberMatcher(double value) { - _value = value; - } - - public boolean matches(Eval x) { - if(x instanceof StringEval) { - // if the target(x) is a string, but parses as a number - // it may still count as a match - StringEval se = (StringEval)x; - Double val = parseDouble(se.getStringValue()); - if(val == null) { - // x is text that is not a number - return false; - } - return val.doubleValue() == _value; - } - if(!(x instanceof NumberEval)) { - return false; - } - NumberEval ne = (NumberEval) x; - return ne.getNumberValue() == _value; - } - } - private static final class BooleanMatcher implements I_MatchPredicate { - - private final boolean _value; - - public BooleanMatcher(boolean value) { - _value = value; - } - - public boolean matches(Eval x) { - if(x instanceof StringEval) { - StringEval se = (StringEval)x; - Boolean val = parseBoolean(se.getStringValue()); - if(val == null) { - // x is text that is not a boolean - return false; - } - if (true) { // change to false to observe more intuitive behaviour - // Note - Unlike with numbers, it seems that COUNTA never matches - // boolean values when the target(x) is a string - return false; - } - return val.booleanValue() == _value; - } - if(!(x instanceof BoolEval)) { - return false; - } - BoolEval be = (BoolEval) x; - return be.getBooleanValue() == _value; - } - } - private static final class StringMatcher implements I_MatchPredicate { - - private final String _value; - - public StringMatcher(String value) { - _value = value; - } - - public boolean matches(Eval x) { - if(!(x instanceof StringEval)) { - return false; - } - StringEval se = (StringEval) x; - return se.getStringValue() == _value; - } - } - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - switch(args.length) { - case 2: - // expected - break; - default: - // TODO - it doesn't seem to be possible to enter COUNTIF() into Excel with the wrong arg count - // perhaps this should be an exception - return ErrorEval.VALUE_INVALID; - } - - AreaEval range = (AreaEval) args[0]; - Eval criteriaArg = args[1]; - if(criteriaArg instanceof RefEval) { - // criteria is not a literal value, but a cell reference - // for example COUNTIF(B2:D4, E1) - RefEval re = (RefEval)criteriaArg; - criteriaArg = re.getInnerValueEval(); - } else { - // other non literal tokens such as function calls, have been fully evaluated - // for example COUNTIF(B2:D4, COLUMN(E1)) - } - I_MatchPredicate mp = createCriteriaPredicate(criteriaArg); - return countMatchingCellsInArea(range, mp); - } - /** - * @return the number of evaluated cells in the range that match the specified criteria - */ - private Eval countMatchingCellsInArea(AreaEval range, I_MatchPredicate criteriaPredicate) { - ValueEval[] values = range.getValues(); - int result = 0; - for (int i = 0; i < values.length; i++) { - if(criteriaPredicate.matches(values[i])) { - result++; - } - } - return new NumberEval(result); - } - - private static I_MatchPredicate createCriteriaPredicate(Eval evaluatedCriteriaArg) { - if(evaluatedCriteriaArg instanceof NumberEval) { - return new NumberMatcher(((NumberEval)evaluatedCriteriaArg).getNumberValue()); - } - if(evaluatedCriteriaArg instanceof BoolEval) { - return new BooleanMatcher(((BoolEval)evaluatedCriteriaArg).getBooleanValue()); - } - - if(evaluatedCriteriaArg instanceof StringEval) { - return createGeneralMatchPredicate((StringEval)evaluatedCriteriaArg); - } - throw new RuntimeException("Unexpected type for criteria (" - + evaluatedCriteriaArg.getClass().getName() + ")"); - } - - /** - * When the second argument is a string, many things are possible - */ - private static I_MatchPredicate createGeneralMatchPredicate(StringEval stringEval) { - String value = stringEval.getStringValue(); - char firstChar = value.charAt(0); - Boolean booleanVal = parseBoolean(value); - if(booleanVal != null) { - return new BooleanMatcher(booleanVal.booleanValue()); - } - - Double doubleVal = parseDouble(value); - if(doubleVal != null) { - return new NumberMatcher(doubleVal.doubleValue()); - } - switch(firstChar) { - case '>': - case '<': - case '=': - throw new RuntimeException("Incomplete code - criteria expressions such as '" - + value + "' not supported yet"); - } - - //else - just a plain string with no interpretation. - return new StringMatcher(value); - } - - /** - * Under certain circumstances COUNTA will equate a plain number with a string representation of that number - */ - /* package */ static Double parseDouble(String strRep) { - if(!Character.isDigit(strRep.charAt(0))) { - // avoid using NumberFormatException to tell when string is not a number - return null; - } - // TODO - support notation like '1E3' (==1000) - - double val; - try { - val = Double.parseDouble(strRep); - } catch (NumberFormatException e) { - return null; - } - return new Double(val); - } - /** - * Boolean literals ('TRUE', 'FALSE') treated similarly but NOT same as numbers. - */ - /* package */ static Boolean parseBoolean(String strRep) { - switch(strRep.charAt(0)) { - case 't': - case 'T': - if("TRUE".equalsIgnoreCase(strRep)) { - return Boolean.TRUE; - } - break; - case 'f': - case 'F': - if("FALSE".equalsIgnoreCase(strRep)) { - return Boolean.FALSE; - } - break; - } - return null; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Covar.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Covar.java deleted file mode 100644 index fc1188992d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Covar.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Covar extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Critbinom.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Critbinom.java deleted file mode 100644 index 3a3d1a67b9..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Critbinom.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Critbinom extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Customrepeat.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Customrepeat.java deleted file mode 100644 index 4206a173fa..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Customrepeat.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Customrepeat extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java deleted file mode 100644 index 6861a02524..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Date.java +++ /dev/null @@ -1,114 +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.Calendar; -import java.util.GregorianCalendar; - -import org.apache.poi.hssf.usermodel.HSSFDateUtil; - -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -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.ValueEval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; - -/** - * @author Pavel Krupets (pkrupets at palmtreebusiness dot com) - */ -public class Date extends NumericFunction { - /** - * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) - */ - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - if (operands.length == 3) { - ValueEval ve[] = new ValueEval[3]; - - ve[0] = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - ve[1] = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); - ve[2] = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol); - - if (validValues(ve)) { - int year = getYear(ve[0]); - int month = (int) ((NumericValueEval) ve[1]).getNumberValue() - 1; - int day = (int) ((NumericValueEval) ve[2]).getNumberValue(); - - if (year < 0 || month < 0 || day < 0) { - return ErrorEval.VALUE_INVALID; - } - - if (year == 1900 && month == Calendar.FEBRUARY && day == 29) { - return new NumberEval(60.0); - } - - if (year == 1900) { - if ((month == Calendar.JANUARY && day >= 60) || - (month == Calendar.FEBRUARY && day >= 30)) - { - day--; - } - } - - Calendar c = new GregorianCalendar(); - - c.set(year, month, day, 0, 0, 0); - c.set(Calendar.MILLISECOND, 0); - - return new NumberEval(HSSFDateUtil.getExcelDate(c.getTime(), false)); // XXX fix 1900/1904 problem - } - } - - return ErrorEval.VALUE_INVALID; - } - - private int getYear(ValueEval ve) { - int year = (int) ((NumericValueEval) ve).getNumberValue(); - - if (year < 0) { - return -1; - } - - return year < 1900 ? 1900 + year : year; - } - - private boolean validValues(ValueEval[] values) { - for (int i = 0; i < values.length; i++) { - ValueEval value = values[i]; - - if (value instanceof RefEval) { - RefEval re = (RefEval) value; - ValueEval ive = re.getInnerValueEval(); - - if (ive instanceof BlankEval) { - value = new NumberEval(0); - } else if (ive instanceof NumericValueEval) { - value = ive; - } else { - return false; - } - } - - if (!(value instanceof NumericValueEval)) { - return false; - } - } - - return true; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datedif.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datedif.java deleted file mode 100644 index 1a14516049..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datedif.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Datedif extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datestring.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datestring.java deleted file mode 100644 index 0a80110b79..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datestring.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Datestring extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datevalue.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datevalue.java deleted file mode 100644 index a0377527cf..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Datevalue.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Datevalue extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Daverage.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Daverage.java deleted file mode 100644 index ebf9c28bce..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Daverage.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Daverage extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Day.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Day.java deleted file mode 100644 index 0ae5694767..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Day.java +++ /dev/null @@ -1,64 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.usermodel.HSSFDateUtil; - -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; - -/** - * @author Pavel Krupets - */ -public class Day extends NumericFunction { - /** - * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) - */ - public Eval evaluate(Eval[] operands, int srcCellRow, short -srcCellCol) { - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], -srcCellRow, srcCellCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { - java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem - java.util.Calendar c = java.util.Calendar.getInstance(); - c.setTime(d); - retval = new NumberEval(c.get(java.util.Calendar.DAY_OF_MONTH)); - } else { - retval = ErrorEval.NUM_ERROR; - } - } else if (ve instanceof BlankEval) { - // do nothing - } else { - retval = ErrorEval.NUM_ERROR; - } - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Days360.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Days360.java deleted file mode 100644 index 2187576429..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Days360.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Days360 extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Db.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Db.java deleted file mode 100644 index 1dd80b6af7..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Db.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Db extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dbcs.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dbcs.java deleted file mode 100644 index 30ad221bcf..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dbcs.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dbcs extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dcount.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dcount.java deleted file mode 100644 index 1d64ae2595..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dcount.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dcount extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dcounta.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dcounta.java deleted file mode 100644 index 72d36bc0fd..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dcounta.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dcounta extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ddb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ddb.java deleted file mode 100644 index 66b5a33e08..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ddb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Ddb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Degrees.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Degrees.java deleted file mode 100644 index e85e14d567..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Degrees.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Degrees extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.toDegrees(d); - retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Deref.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Deref.java deleted file mode 100644 index bb773522b2..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Deref.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Deref extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Devsq.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Devsq.java deleted file mode 100644 index a198ff8398..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Devsq.java +++ /dev/null @@ -1,77 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Devsq extends MultiOperandNumericFunction { - - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) (0 - | ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED - )); - - /** - * this is the default impl for the factory method getXlator - * of the super class NumericFunction. Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = StatsLib.devsq(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dget.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dget.java deleted file mode 100644 index ebd846333b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dget.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dget extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dmax.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dmax.java deleted file mode 100644 index 18ea2bdc7b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dmax.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dmax extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dmin.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dmin.java deleted file mode 100644 index 9307af584a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dmin.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dmin extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dollar.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dollar.java deleted file mode 100644 index a65f65a3e7..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dollar.java +++ /dev/null @@ -1,64 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Dollar extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dproduct.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dproduct.java deleted file mode 100644 index bf86748d2c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dproduct.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dproduct extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dstdev.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dstdev.java deleted file mode 100644 index 0cdb4c237f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dstdev.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dstdev extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dstdevp.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dstdevp.java deleted file mode 100644 index e9a2bfaf13..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dstdevp.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dstdevp extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dsum.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dsum.java deleted file mode 100644 index 3c057ca28b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dsum.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dsum extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dvar.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dvar.java deleted file mode 100644 index 764cf618c4..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dvar.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dvar extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dvarp.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dvarp.java deleted file mode 100644 index 03928b77d4..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Dvarp.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Dvarp extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Echo.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Echo.java deleted file mode 100644 index 87d4e29bf8..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Echo.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Echo extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Error.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Error.java deleted file mode 100644 index 41a7ecd9d4..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Error.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Error extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Errortype.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Errortype.java deleted file mode 100644 index 51268c9aa0..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Errortype.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Errortype extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Evaluate.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Evaluate.java deleted file mode 100644 index d458875406..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Evaluate.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Evaluate extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Even.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Even.java deleted file mode 100644 index 9149671676..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Even.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 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Even extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - if (!Double.isNaN(d) && !Double.isInfinite(d)) { - d = (d==0) - ? 0 - : (((long) (d/2))*2 == d) - ? d - : (d < 0) - ? ((((long) (d/2))<<1)-2) - : ((((long) (d/2))<<1)+2); - } - retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exact.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exact.java deleted file mode 100644 index 63dc18d771..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exact.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.StringValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Exact extends TextFunction { - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - String s0 = null; - String s1 = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - if (ve instanceof StringValueEval) { - StringValueEval sve = (StringValueEval) ve; - s0 = sve.getStringValue(); - } - else if (ve instanceof BlankEval) { - s0 = StringEval.EMPTY_INSTANCE.getStringValue(); - } - else { - retval = ErrorEval.VALUE_INVALID; - break; - } - - if (retval == null) { - ve = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); - if (ve instanceof StringValueEval) { - StringValueEval sve = (StringValueEval) ve; - s1 = sve.getStringValue(); - } - else if (ve instanceof BlankEval) { - s1 = StringEval.EMPTY_INSTANCE.getStringValue(); - } - else { - retval = ErrorEval.VALUE_INVALID; - break; - } - } - } - - if (retval == null) { - boolean b = s0.equals(s1); - retval = b ? BoolEval.TRUE : BoolEval.FALSE; - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exec.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exec.java deleted file mode 100644 index 327ba77f4e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exec.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Exec extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exp.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exp.java deleted file mode 100644 index d0b122ab16..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Exp.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Exp extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.pow(E, d); - retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Expondist.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Expondist.java deleted file mode 100644 index 5ba8727d9d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Expondist.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Expondist extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fact.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fact.java deleted file mode 100644 index 128b167c65..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fact.java +++ /dev/null @@ -1,74 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 22, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Fact extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - if (d < Integer.MAX_VALUE && d >= 0) { - d = MathX.factorial((int) d); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : (Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/False.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/False.java deleted file mode 100644 index 2a16b1c73a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/False.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. -*/ -/* - * Created on May 6, 2005 - * - */ -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class False implements Function { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval; - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 0: - retval = BoolEval.FALSE; - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fdist.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fdist.java deleted file mode 100644 index be27363247..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fdist.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Fdist extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Files.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Files.java deleted file mode 100644 index 156fc67012..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Files.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Files extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java deleted file mode 100644 index c054c6dac4..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceFunction.java +++ /dev/null @@ -1,71 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * Super class for all Evals for financial function evaluation. - * - */ -public abstract class FinanceFunction extends NumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) (0 - | ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - | ValueEvalToNumericXlator.BLANK_IS_PARSED - | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - )); - - /** - * this is the default impl of the factory(ish) method getXlator. - * Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected final ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - protected final ValueEval singleOperandNumericAsBoolean(Eval eval, int srcRow, short srcCol) { - ValueEval retval = null; - retval = singleOperandEvaluate(eval, srcRow, srcCol); - if (retval instanceof NumericValueEval) { - NumericValueEval nve = (NumericValueEval) retval; - retval = (nve.getNumberValue() == 0) - ? BoolEval.FALSE - : BoolEval.TRUE; - } - else { - retval = ErrorEval.VALUE_INVALID; - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceLib.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceLib.java deleted file mode 100644 index 96f8717a2c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/FinanceLib.java +++ /dev/null @@ -1,190 +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 21, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - * - * This class is a functon library for common fiscal functions. - * Glossary of terms/abbreviations: - *
    - *

      - *
    • FV: Future Value
    • - *
    • PV: Present Value
    • - *
    • NPV: Net Present Value
    • - *
    • PMT: (Periodic) Payment
    • - * - *
    - * For more info on the terms/abbreviations please use the references below - * (hyperlinks are subject to change): - *
    Online References: - *
      - *
    1. GNU Emacs Calc 2.02 Manual: http://theory.uwinnipeg.ca/gnu/calc/calc_203.html
    2. - *
    3. Yahoo Financial Glossary: http://biz.yahoo.com/f/g/nn.html#y
    4. - *
    5. MS Excel function reference: http://office.microsoft.com/en-us/assistance/CH062528251033.aspx
    6. - *
    - *

    Implementation Notes:

    - * Symbols used in the formulae that follow:
    - *
      - *
    • p: present value
    • - *
    • f: future value
    • - *
    • n: number of periods
    • - *
    • y: payment (in each period)
    • - *
    • r: rate
    • - *
    • ^: the power operator (NOT the java bitwise XOR operator!)
    • - *
    - * [From MS Excel function reference] Following are some of the key formulas - * that are used in this implementation: - *
    - * p(1+r)^n + y(1+rt)((1+r)^n-1)/r + f=0   ...{when r!=0}
    - * ny + p + f=0                            ...{when r=0}
    - * 
    - */ -public final class FinanceLib { - - // constants for default values - - - - private FinanceLib() {} - - /** - * 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 - * Two important functions with this feature are INDIRECT and OFFSET

    - * - * In POI, the HSSFFormulaEvaluator evaluates every cell in each reference argument before - * calling the function. This means that functions using fixed references do not need access to - * the rest of the workbook to execute. Hence the evaluate() method on the common - * interface Function does not take a workbook parameter.

    - * - * This interface recognises the requirement of some functions to freely create and evaluate - * references beyond those passed in as arguments. - * - * @author Josh Micich - */ -public interface FreeRefFunction { - /** - * - * @param args the pre-evaluated arguments for this function. args is never null, - * nor are any of its elements. - * @param srcCellRow zero based row index of the cell containing the currently evaluating formula - * @param srcCellCol zero based column index of the cell containing the currently evaluating formula - * @param workbook is the workbook containing the formula/cell being evaluated - * @param sheet is the sheet containing the formula/cell being evaluated - * @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(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet); -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Frequency.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Frequency.java deleted file mode 100644 index fc003c3e2e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Frequency.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Frequency extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ftest.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ftest.java deleted file mode 100644 index fb662027ef..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ftest.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Ftest extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Function.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Function.java deleted file mode 100644 index e33514a463..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Function.java +++ /dev/null @@ -1,33 +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 9, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.Eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * Function serves as a marker interface. - */ -public interface Function { - - public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol); - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fv.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fv.java deleted file mode 100644 index fd0335c388..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Fv.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. -*/ -/* - * Created on May 15, 2005 - * - */ -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Fv extends FinanceFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double rate = 0, nper = 0, pmt = 0, pv = 0, d = 0; - boolean type = false; - ValueEval retval = null; - ValueEval ve = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 5: - ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol); - if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; } - type = ((BoolEval) ve).getBooleanValue(); - case 4: - ve = singleOperandEvaluate(operands[3], srcRow, srcCol); - if (ve instanceof NumericValueEval) pv = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - case 3: - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) nper = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - - ve = singleOperandEvaluate(operands[2], srcRow, srcCol); - if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - - ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - } - - if (retval == null) { - d = FinanceLib.fv(rate, nper, pmt, pv, type); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : (Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammadist.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammadist.java deleted file mode 100644 index fa788c55e5..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammadist.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Gammadist extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammainv.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammainv.java deleted file mode 100644 index ea8bdc53be..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammainv.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Gammainv extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammaln.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammaln.java deleted file mode 100644 index fb6026657a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Gammaln.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Gammaln extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Geomean.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Geomean.java deleted file mode 100644 index 1669a78901..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Geomean.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Geomean extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Goto.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Goto.java deleted file mode 100644 index c1a4d596da..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Goto.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Goto extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Group.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Group.java deleted file mode 100644 index 91c6cc5d18..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Group.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Group extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Growth.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Growth.java deleted file mode 100644 index 5a35a2b24b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Growth.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Growth extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Halt.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Halt.java deleted file mode 100644 index 74ce5761c6..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Halt.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Halt extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Harmean.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Harmean.java deleted file mode 100644 index ade3109a1b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Harmean.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Harmean extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Help.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Help.java deleted file mode 100644 index 1bf4004ac1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Help.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Help extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hlookup.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hlookup.java deleted file mode 100644 index 40ed1da490..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hlookup.java +++ /dev/null @@ -1,123 +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.Eval; -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; -/** - * Implementation of the VLOOKUP() function.

    - * - * HLOOKUP finds a column in a lookup table by the first row value and returns the value from another row. - * - * Syntax:
    - * HLOOKUP(lookup_value, table_array, row_index_num, range_lookup)

    - * - * lookup_value The value to be found in the first column of the table array.
    - * table_array An area reference for the lookup data.
    - * row_index_num a 1 based index specifying which row value of the lookup data will be returned.
    - * range_lookup If TRUE (default), HLOOKUP finds the largest value less than or equal to - * the lookup_value. If FALSE, only exact matches will be considered
    - * - * @author Josh Micich - */ -public final class Hlookup implements Function { - - private static final class RowVector implements ValueVector { - - private final AreaEval _tableArray; - private final int _size; - private final int _rowAbsoluteIndex; - private final int _firstColumnAbsoluteIndex; - - public RowVector(AreaEval tableArray, int rowIndex) { - _rowAbsoluteIndex = tableArray.getFirstRow() + rowIndex; - if(!tableArray.containsRow(_rowAbsoluteIndex)) { - int lastRowIx = tableArray.getLastRow() - tableArray.getFirstRow(); - throw new IllegalArgumentException("Specified row index (" + rowIndex - + ") is outside the allowed range (0.." + lastRowIx + ")"); - } - _tableArray = tableArray; - _size = tableArray.getLastColumn() - tableArray.getFirstColumn() + 1; - if(_size < 1) { - throw new RuntimeException("bad table array size zero"); - } - _firstColumnAbsoluteIndex = tableArray.getFirstColumn(); - } - - public ValueEval getItem(int index) { - if(index>_size) { - throw new ArrayIndexOutOfBoundsException("Specified index (" + index - + ") is outside the allowed range (0.." + (_size-1) + ")"); - } - return _tableArray.getValueAt(_rowAbsoluteIndex, (short) (_firstColumnAbsoluteIndex + index)); - } - public int getSize() { - return _size; - } - } - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - Eval arg3 = null; - switch(args.length) { - case 4: - arg3 = args[3]; // important: assumed array element is never null - case 3: - break; - default: - // wrong number of arguments - return ErrorEval.VALUE_INVALID; - } - try { - // Evaluation order: - // arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 row_index, fetch result - ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - AreaEval tableArray = LookupUtils.resolveTableArrayArg(args[1]); - boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcCellRow, srcCellCol); - int colIndex = LookupUtils.lookupIndexOfValue(lookupValue, new RowVector(tableArray, 0), isRangeLookup); - ValueEval veColIndex = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol); - int rowIndex = LookupUtils.resolveRowOrColIndexArg(veColIndex); - ValueVector resultCol = createResultColumnVector(tableArray, rowIndex); - return resultCol.getItem(colIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - - /** - * Returns one column from an AreaEval - * - * @throws EvaluationException (#VALUE!) if colIndex is negative, (#REF!) if colIndex is too high - */ - private ValueVector createResultColumnVector(AreaEval tableArray, int colIndex) throws EvaluationException { - if(colIndex < 0) { - throw EvaluationException.invalidValue(); - } - int nCols = tableArray.getLastColumn() - tableArray.getFirstRow() + 1; - - if(colIndex >= nCols) { - throw EvaluationException.invalidRef(); - } - return new RowVector(tableArray, colIndex); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hour.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hour.java deleted file mode 100644 index 0caeda4d8c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hour.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Hour extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hyperlink.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hyperlink.java deleted file mode 100644 index 020d40d87f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hyperlink.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Hyperlink extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hypgeomdist.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hypgeomdist.java deleted file mode 100644 index 9c76cc148a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Hypgeomdist.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Hypgeomdist extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.java deleted file mode 100644 index 7aba5db72a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/If.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. -*/ -/* - * Created on Nov 25, 2006 - * - */ -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class If implements Function { - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - - Eval evalWhenFalse = BoolEval.FALSE; - switch (args.length) { - case 3: - evalWhenFalse = args[2]; - case 2: - BoolEval beval = (BoolEval) args[0]; // TODO - class cast exception - if (beval.getBooleanValue()) { - return args[1]; - } - return evalWhenFalse; - default: - return ErrorEval.VALUE_INVALID; - } - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Index.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Index.java deleted file mode 100644 index aebf6aab0d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Index.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.AreaEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; - -/** - * Implementation for the Excel function INDEX

    - * - * Syntax :
    - * INDEX ( reference, row_num[, column_num [, area_num]])
    - * INDEX ( array, row_num[, column_num]) - * - * - * - * - * - * - *
    referencetypically an area reference, possibly a union of areas
    arraya literal array value (currently not supported)
    row_numselects the row within the array or area reference
    column_numselects column within the array or area reference. default is 1
    area_numused when reference is a union of areas
    - *

    - * - * @author Josh Micich - */ -public final class Index implements Function { - - // TODO - javadoc for interface method - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - int nArgs = args.length; - if(nArgs < 2) { - // too few arguments - return ErrorEval.VALUE_INVALID; - } - Eval firstArg = args[0]; - if(firstArg instanceof AreaEval) { - AreaEval reference = (AreaEval) firstArg; - - int rowIx = 0; - int columnIx = 0; - int areaIx = 0; - switch(nArgs) { - case 4: - areaIx = convertIndexArgToZeroBase(args[3]); - throw new RuntimeException("Incomplete code" + - " - don't know how to support the 'area_num' parameter yet)"); - // Excel expression might look like this "INDEX( (A1:B4, C3:D6, D2:E5 ), 1, 2, 3) - // In this example, the 3rd area would be used i.e. D2:E5, and the overall result would be E2 - // Token array might be encoded like this: MemAreaPtg, AreaPtg, AreaPtg, UnionPtg, UnionPtg, ParenthesesPtg - // The formula parser doesn't seem to support this yet. Not sure if the evaluator does either - - case 3: - columnIx = convertIndexArgToZeroBase(args[2]); - case 2: - rowIx = convertIndexArgToZeroBase(args[1]); - break; - default: - // too many arguments - return ErrorEval.VALUE_INVALID; - } - - int nColumns = reference.getLastColumn()-reference.getFirstColumn()+1; - int index = rowIx * nColumns + columnIx; - - return reference.getValues()[index]; - } - - // else the other variation of this function takes an array as the first argument - // it seems like interface 'ArrayEval' does not even exist yet - - throw new RuntimeException("Incomplete code - cannot handle first arg of type (" - + firstArg.getClass().getName() + ")"); - } - - /** - * takes a NumberEval representing a 1-based index and returns the zero-based int value - */ - private static int convertIndexArgToZeroBase(Eval ev) { - NumberEval ne; - if(ev instanceof RefEval) { - // TODO - write junit to justify this - RefEval re = (RefEval) ev; - ne = (NumberEval) re.getInnerValueEval(); - } else { - ne = (NumberEval)ev; - } - - return (int)ne.getNumberValue() - 1; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Indirect.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Indirect.java deleted file mode 100644 index 935e7cdbbd..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Indirect.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.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -/** - * Implementation for Excel function INDIRECT

    - * - * INDIRECT() returns the cell or area reference denoted by the text argument.

    - * - * Syntax:
    - * INDIRECT(ref_text,isA1Style)

    - * - * ref_text a string representation of the desired reference as it would normally be written - * in a cell formula.
    - * isA1Style (default TRUE) specifies whether the ref_text should be interpreted as A1-style - * or R1C1-style. - * - * - * @author Josh Micich - */ -public final class Indirect implements FreeRefFunction { - - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { - // TODO - implement INDIRECT() - return ErrorEval.FUNCTION_NOT_IMPLEMENTED; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Info.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Info.java deleted file mode 100644 index 2b542dd717..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Info.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Info extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Initiate.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Initiate.java deleted file mode 100644 index 6795c7aeb1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Initiate.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Initiate extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Input.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Input.java deleted file mode 100644 index 0d3614c796..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Input.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Input extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Int.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Int.java deleted file mode 100644 index 5b26a8a8a1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Int.java +++ /dev/null @@ -1,69 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Int extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - if (d < 0) { - d = Math.round(d-0.5); - } - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval((long) d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Intercept.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Intercept.java deleted file mode 100644 index bf94b5ba29..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Intercept.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Intercept extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ipmt.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ipmt.java deleted file mode 100644 index 61e85a4d5b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ipmt.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Ipmt extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Irr.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Irr.java deleted file mode 100644 index f23325e4f9..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Irr.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Irr extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/IsError.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/IsError.java deleted file mode 100644 index 786060704e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/IsError.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. -*/ -/* - * Created on May 15, 2005 - * - */ -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.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class IsError implements Function { - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - boolean b = false; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - if (operands[0] instanceof ErrorEval) { - b = true; - } - else if (operands[0] instanceof AreaEval) { - AreaEval ae = (AreaEval) operands[0]; - if (ae.contains(srcCellRow, srcCellCol)) { // circular ref! - retval = ErrorEval.CIRCULAR_REF_ERROR; - } - else if (ae.isRow()) { - if (ae.containsColumn(srcCellCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCellCol); - if (ve instanceof RefEval) - b = ((RefEval) ve).getInnerValueEval() instanceof ErrorEval; - else - b = (ve instanceof ErrorEval); - } - else { - b = true; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcCellRow)) { - ValueEval ve = ae.getValueAt(srcCellRow, ae.getFirstColumn()); - if (ve instanceof RefEval) - b = ((RefEval) ve).getInnerValueEval() instanceof ErrorEval; - else - b = (ve instanceof ErrorEval); - } - else { - b = true; - } - } - else { - b = true; - } - } - else if (operands[0] instanceof RefEval) { - b = ((RefEval) operands[0]).getInnerValueEval() instanceof ErrorEval; - } - else { - b = false; - } - } - - if (retval == null) { - retval = b - ? BoolEval.TRUE - : BoolEval.FALSE; - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/IsNa.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/IsNa.java deleted file mode 100644 index b1f8f09641..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/IsNa.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class IsNa extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java deleted file mode 100644 index c0e482e5a8..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isblank.java +++ /dev/null @@ -1,48 +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.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.EvaluationException; -import org.apache.poi.hssf.record.formula.eval.OperandResolver; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Isblank implements Function { - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - if(args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - Eval arg = args[0]; - - ValueEval singleCellValue; - try { - singleCellValue = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - } catch (EvaluationException e) { - return BoolEval.FALSE; - } - return BoolEval.valueOf(singleCellValue instanceof BlankEval); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Iserr.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Iserr.java deleted file mode 100644 index f1ebd48fbd..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Iserr.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Iserr extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Islogical.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Islogical.java deleted file mode 100644 index 318d1e69f1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Islogical.java +++ /dev/null @@ -1,57 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Islogical extends LogicalFunction { - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = BoolEval.FALSE; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - Eval eval = operands[0]; - if (eval instanceof BoolEval) { - retval = BoolEval.TRUE; - } - else if (eval instanceof RefEval) { - Eval xlatedEval = xlateRefEval((RefEval) eval); - if (xlatedEval instanceof BoolEval) { - retval = BoolEval.TRUE; - } - } - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isnontext.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isnontext.java deleted file mode 100644 index eb07e63eb8..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isnontext.java +++ /dev/null @@ -1,56 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Isnontext extends LogicalFunction { - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = BoolEval.TRUE; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - Eval eval = operands[0]; - if (eval instanceof StringEval) { - retval = BoolEval.FALSE; - } - else if (eval instanceof RefEval) { - Eval xlatedEval = xlateRefEval((RefEval) eval); - if (xlatedEval instanceof StringEval) { - retval = BoolEval.FALSE; - } - } - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isnumber.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isnumber.java deleted file mode 100644 index e3ff8d49aa..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isnumber.java +++ /dev/null @@ -1,56 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Isnumber extends LogicalFunction { - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = BoolEval.FALSE; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - Eval eval = operands[0]; - if (eval instanceof NumberEval) { - retval = BoolEval.TRUE; - } - else if (eval instanceof RefEval) { - Eval xlatedEval = xlateRefEval((RefEval) eval); - if (xlatedEval instanceof NumberEval) { - retval = BoolEval.TRUE; - } - } - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ispmt.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ispmt.java deleted file mode 100644 index 69c7f428c3..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ispmt.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Ispmt extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isref.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isref.java deleted file mode 100644 index 1deb606544..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Isref.java +++ /dev/null @@ -1,50 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.AreaEval; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Isref implements Function { - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = BoolEval.FALSE; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - Eval eval = operands[0]; - if (eval instanceof RefEval || eval instanceof AreaEval) { - retval = BoolEval.TRUE; - } - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Istext.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Istext.java deleted file mode 100644 index ec87d79cbd..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Istext.java +++ /dev/null @@ -1,56 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Istext extends LogicalFunction { - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = BoolEval.FALSE; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - Eval eval = operands[0]; - if (eval instanceof StringEval) { - retval = BoolEval.TRUE; - } - else if (eval instanceof RefEval) { - Eval xlatedEval = xlateRefEval((RefEval) eval); - if (xlatedEval instanceof StringEval) { - retval = BoolEval.TRUE; - } - } - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Kurt.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Kurt.java deleted file mode 100644 index fe4e76eef5..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Kurt.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Kurt extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Large.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Large.java deleted file mode 100644 index 3b9aed9768..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Large.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Large extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) (0 - | ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.BLANK_IS_PARSED - )); - - /** - * this is the default impl for the factory method getXlator - * of the super class NumericFunction. Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] ops = getNumberArray(operands, srcCellRow, srcCellCol); - if (ops == null || ops.length < 2) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double[] values = new double[ops.length-1]; - int k = (int) ops[ops.length-1]; - System.arraycopy(ops, 0, values, 0, values.length); - double d = StatsLib.kthLargest(values, k); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lasterror.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lasterror.java deleted file mode 100644 index c5024a5ad3..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lasterror.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Lasterror extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Left.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Left.java deleted file mode 100644 index ecb14a7008..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Left.java +++ /dev/null @@ -1,107 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.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 > - * - */ -public class Left extends TextFunction { - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = ErrorEval.VALUE_INVALID; - int index = 1; - switch (operands.length) { - default: - break; - case 2: - Eval indexEval = operands[1]; - index = evaluateAsInteger(indexEval); - if (index < 0) { - break; - } - case 1: - ValueEval veval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - String str = null; - if (veval instanceof StringEval) { - StringEval stringEval = (StringEval) veval; - str = stringEval.getStringValue(); - } - else if (veval instanceof BoolEval) { - BoolEval beval = (BoolEval) veval; - str = beval.getBooleanValue() ? "TRUE" : "FALSE"; - } - else if (veval instanceof NumberEval) { - NumberEval neval = (NumberEval) veval; - str = neval.getStringValue(); - } - if (null != str) { - str = str.substring(0, Math.min(str.length(), index)); - retval = new StringEval(str); - } - } - return retval; - } - - protected int evaluateAsInteger(Eval eval) { - int numval = -1; - if (eval instanceof NumberEval) { - NumberEval neval = (NumberEval) eval; - double d = neval.getNumberValue(); - numval = (int) d; - } - else if (eval instanceof StringEval) { - StringEval seval = (StringEval) eval; - String s = seval.getStringValue(); - try { - double d = Double.parseDouble(s); - numval = (int) d; - } - catch (Exception e) { - } - } - else if (eval instanceof BoolEval) { - BoolEval beval = (BoolEval) eval; - numval = beval.getBooleanValue() ? 1 : 0; - } - else if (eval instanceof RefEval) { - numval = evaluateAsInteger(xlateRefEval((RefEval) eval)); - } - return numval; - } - - protected Eval xlateRefEval(RefEval reval) { - Eval retval = reval.getInnerValueEval(); - - if (retval instanceof RefEval) { - retval = xlateRefEval((RefEval) retval); - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Leftb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Leftb.java deleted file mode 100644 index 9c3d362970..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Leftb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Leftb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.java deleted file mode 100644 index 0bc49b4070..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Len.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.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.EvaluationException; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.OperandResolver; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Len extends TextFunction { - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - - if(args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - - try { - ValueEval veval = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - - String str = OperandResolver.coerceValueToString(veval); - - return new NumberEval(str.length()); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lenb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lenb.java deleted file mode 100644 index b47105aa13..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lenb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Lenb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Linest.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Linest.java deleted file mode 100644 index ea415a40c1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Linest.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Linest extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Links.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Links.java deleted file mode 100644 index 1f2d570204..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Links.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Links extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ln.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ln.java deleted file mode 100644 index 95392a4d17..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ln.java +++ /dev/null @@ -1,66 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Ln extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.log(d); - retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log.java deleted file mode 100644 index 7727c35275..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log.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. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * Log: LOG(number,[base]) - */ -public class Log extends NumericFunction { - - private static final double DEFAULT_BASE = 10; - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - double base = DEFAULT_BASE; - double num = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: // second arg is base - ValueEval ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - base = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - case 1: // first arg is number - if (retval == null) { - ValueEval vev = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (vev instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) vev; - num = ne.getNumberValue(); - } - else if (vev instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - d = (base == E) - ? Math.log(num) - : Math.log(num) / Math.log(base); - retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log10.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log10.java deleted file mode 100644 index cf8b9bd138..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Log10.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Log10 extends NumericFunction { - private static final double LOG_10_TO_BASE_e = Math.log(10); - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.log(d) / LOG_10_TO_BASE_e; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Logest.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Logest.java deleted file mode 100644 index 2a36f7dad2..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Logest.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Logest extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.java deleted file mode 100644 index 03756e1faf..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LogicalFunction.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. -*/ -/* - * Created on Nov 25, 2006 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class LogicalFunction implements Function { - - /** - * recursively evaluate any RefEvals - * @param reval - */ - protected ValueEval xlateRefEval(RefEval reval) { - ValueEval retval = (ValueEval) reval.getInnerValueEval(); - - if (retval instanceof RefEval) { - RefEval re = (RefEval) retval; - retval = xlateRefEval(re); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Loginv.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Loginv.java deleted file mode 100644 index 8b885ca506..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Loginv.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Loginv extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lognormdist.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lognormdist.java deleted file mode 100644 index 26ca53baec..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lognormdist.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Lognormdist extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lookup.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lookup.java deleted file mode 100644 index be1d0d0f94..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Lookup.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.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.Eval; -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; - -/** - * Implementation of Excel function LOOKUP.

    - * - * LOOKUP finds an index row in a lookup table by the first column value and returns the value from another column. - * - * Syntax:
    - * VLOOKUP(lookup_value, lookup_vector, result_vector)

    - * - * lookup_value The value to be found in the lookup vector.
    - * lookup_vector An area reference for the lookup data.
    - * result_vector Single row or single column area reference from which the result value is chosen.
    - * - * @author Josh Micich - */ -public final class Lookup implements Function { - private static final class SimpleValueVector implements ValueVector { - private final ValueEval[] _values; - - public SimpleValueVector(ValueEval[] values) { - _values = values; - } - public ValueEval getItem(int index) { - return _values[index]; - } - public int getSize() { - return _values.length; - } - } - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - switch(args.length) { - case 3: - break; - case 2: - // complex rules to choose lookupVector and resultVector from the single area ref - throw new RuntimeException("Two arg version of LOOKUP not supported yet"); - default: - return ErrorEval.VALUE_INVALID; - } - - - try { - ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - AreaEval aeLookupVector = LookupUtils.resolveTableArrayArg(args[1]); - AreaEval aeResultVector = LookupUtils.resolveTableArrayArg(args[2]); - - ValueVector lookupVector = createVector(aeLookupVector); - ValueVector resultVector = createVector(aeResultVector); - if(lookupVector.getSize() > resultVector.getSize()) { - // Excel seems to handle this by accessing past the end of the result vector. - throw new RuntimeException("Lookup vector and result vector of differing sizes not supported yet"); - } - int index = LookupUtils.lookupIndexOfValue(lookupValue, lookupVector, true); - - return resultVector.getItem(index); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private static ValueVector createVector(AreaEval ae) { - - if(!ae.isRow() && !ae.isColumn()) { - // extra complexity required to emulate the way LOOKUP can handles these abnormal cases. - throw new RuntimeException("non-vector lookup or result areas not supported yet"); - } - return new SimpleValueVector(ae.getValues()); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LookupUtils.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LookupUtils.java deleted file mode 100644 index d6a8489623..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/LookupUtils.java +++ /dev/null @@ -1,530 +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.AreaPtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.EvaluationException; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -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; - -/** - * Common functionality used by VLOOKUP, HLOOKUP, LOOKUP and MATCH - * - * @author Josh Micich - */ -final class LookupUtils { - - /** - * Represents a single row or column within an AreaEval. - */ - public interface ValueVector { - ValueEval getItem(int index); - int getSize(); - } - /** - * 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 _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; - } - if (_targetClass == StringEval.class) { - - } - 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).
    - * Sample behaviour: - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Input   ReturnValue  Thrown Error
    54 
    2.92 
    "5"4 
    "2.18e1"21 
    "-$2"-3*
    FALSE-1*
    TRUE0 
    "TRUE" #REF!
    "abc" #REF!
    "" #REF!
    <blank> #VALUE!

    - * - * * Note - out of range errors (both too high and too low) are handled by the caller. - * @return column or row index as a zero-based value - * - */ - public static int resolveRowOrColIndexArg(ValueEval veRowColIndexArg) throws EvaluationException { - if(veRowColIndexArg == null) { - throw new IllegalArgumentException("argument must not be null"); - } - if(veRowColIndexArg instanceof BlankEval) { - throw EvaluationException.invalidValue(); - } - if(veRowColIndexArg instanceof StringEval) { - StringEval se = (StringEval) veRowColIndexArg; - String strVal = se.getStringValue(); - Double dVal = OperandResolver.parseDouble(strVal); - if(dVal == null) { - // String does not resolve to a number. Raise #VALUE! error. - throw EvaluationException.invalidRef(); - // This includes text booleans "TRUE" and "FALSE". They are not valid. - } - // else - numeric value parses OK - } - // actual BoolEval values get interpreted as FALSE->0 and TRUE->1 - return OperandResolver.coerceValueToInt(veRowColIndexArg) - 1; - } - - - - /** - * The second argument (table_array) should be an area ref, but can actually be a cell ref, in - * which case it is interpreted as a 1x1 area ref. Other scalar values cause #VALUE! error. - */ - public static AreaEval resolveTableArrayArg(Eval eval) throws EvaluationException { - if (eval instanceof AreaEval) { - return (AreaEval) eval; - } - - if(eval instanceof RefEval) { - RefEval refEval = (RefEval) eval; - // Make this cell ref look like a 1x1 area ref. - - // It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval. - // This code only requires the value array item. - // anything would be ok for rowIx and colIx, but may as well get it right. - int rowIx = refEval.getRow(); - int colIx = refEval.getColumn(); - AreaPtg ap = new AreaPtg(rowIx, rowIx, colIx, colIx, false, false, false, false); - ValueEval value = refEval.getInnerValueEval(); - return new Area2DEval(ap, new ValueEval[] { value, }); - } - throw EvaluationException.invalidValue(); - } - - - /** - * Resolves the last (optional) parameter (range_lookup) to the VLOOKUP and HLOOKUP functions. - * @param rangeLookupArg - * @param srcCellRow - * @param srcCellCol - * @return - * @throws EvaluationException - */ - public static boolean resolveRangeLookupArg(Eval rangeLookupArg, int srcCellRow, short srcCellCol) throws EvaluationException { - if(rangeLookupArg == null) { - // range_lookup arg not provided - return true; // default is TRUE - } - 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 lookup - * - * Syntax:
    - * MATCH(lookup_value, lookup_array, match_type)

    - * - * Returns a 1-based index specifying at what position in the lookup_array the specified - * lookup_value is found.

    - * - * Specific matching behaviour can be modified with the optional match_type parameter. - * - * - * - * - * - * - *
    ValueMatching Behaviour
    1(default) find the largest value that is less than or equal to lookup_value. - * The lookup_array must be in ascending order*.
    0find the first value that is exactly equal to lookup_value. - * The lookup_array can be in any order.
    -1find the smallest value that is greater than or equal to lookup_value. - * The lookup_array must be in descending order*.
    - * - * * Note regarding order - For the match_type cases that require the lookup_array to - * be ordered, MATCH() can produce incorrect results if this requirement is not met. Observed - * behaviour in Excel is to return the lowest index value for which every item after that index - * breaks the match rule.
    - * The (ascending) sort order expected by MATCH() is:
    - * numbers (low to high), strings (A to Z), boolean (FALSE to TRUE)
    - * MATCH() ignores all elements in the lookup_array with a different type to the lookup_value. - * Type conversion of the lookup_array elements is never performed. - * - * - * @author Josh Micich - */ -public final class Match implements Function { - - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - - double match_type = 1; // default - - switch(args.length) { - case 3: - try { - match_type = evaluateMatchTypeArg(args[2], srcCellRow, srcCellCol); - } catch (EvaluationException e) { - // Excel/MATCH() seems to have slightly abnormal handling of errors with - // the last parameter. Errors do not propagate up. Every error gets - // translated into #REF! - return ErrorEval.REF_INVALID; - } - case 2: - break; - default: - return ErrorEval.VALUE_INVALID; - } - - boolean matchExact = match_type == 0; - // Note - Excel does not strictly require -1 and +1 - boolean findLargestLessThanOrEqual = match_type > 0; - - - try { - ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - ValueEval[] lookupRange = evaluateLookupRange(args[1]); - int index = findIndexOfValue(lookupValue, lookupRange, matchExact, findLargestLessThanOrEqual); - return new NumberEval(index + 1); // +1 to convert to 1-based - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private static ValueEval[] evaluateLookupRange(Eval eval) throws EvaluationException { - if (eval instanceof RefEval) { - RefEval re = (RefEval) eval; - return new ValueEval[] { re.getInnerValueEval(), }; - } - if (eval instanceof AreaEval) { - AreaEval ae = (AreaEval) eval; - if(!ae.isColumn() && !ae.isRow()) { - throw new EvaluationException(ErrorEval.NA); - } - return ae.getValues(); - } - - // Error handling for lookup_range arg is also unusual - if(eval instanceof NumericValueEval) { - throw new EvaluationException(ErrorEval.NA); - } - if (eval instanceof StringEval) { - StringEval se = (StringEval) eval; - Double d = OperandResolver.parseDouble(se.getStringValue()); - if(d == null) { - // plain string - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - // else looks like a number - throw new EvaluationException(ErrorEval.NA); - } - throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")"); - } - - - - private static double evaluateMatchTypeArg(Eval arg, int srcCellRow, short srcCellCol) - throws EvaluationException { - Eval match_type = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - - if(match_type instanceof ErrorEval) { - throw new EvaluationException((ErrorEval)match_type); - } - if(match_type instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) match_type; - return ne.getNumberValue(); - } - if (match_type instanceof StringEval) { - StringEval se = (StringEval) match_type; - Double d = OperandResolver.parseDouble(se.getStringValue()); - if(d == null) { - // plain string - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } - // if the string parses as a number, it is OK - return d.doubleValue(); - } - throw new RuntimeException("Unexpected match_type type (" + match_type.getClass().getName() + ")"); - } - - /** - * @return zero based index - */ - private static int findIndexOfValue(ValueEval lookupValue, ValueEval[] lookupRange, - boolean matchExact, boolean findLargestLessThanOrEqual) throws EvaluationException { - - LookupValueComparer lookupComparer = createLookupComparer(lookupValue, matchExact); - - if(matchExact) { - for (int i = 0; i < lookupRange.length; i++) { - if(lookupComparer.compareTo(lookupRange[i]).isEqual()) { - return i; - } - } - throw new EvaluationException(ErrorEval.NA); - } - - if(findLargestLessThanOrEqual) { - // Note - backward iteration - for (int i = lookupRange.length - 1; i>=0; i--) { - CompareResult cmp = lookupComparer.compareTo(lookupRange[i]); - if(cmp.isTypeMismatch()) { - continue; - } - if(!cmp.isLessThan()) { - return i; - } - } - throw new EvaluationException(ErrorEval.NA); - } - - // else - find smallest greater than or equal to - // TODO - is binary search used for (match_type==+1) ? - for (int i = 0; i=0 || stringValue.indexOf('*') >=0) { - return true; - } - return false; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MathX.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MathX.java deleted file mode 100644 index 593998f1e9..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MathX.java +++ /dev/null @@ -1,565 +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 19, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - - - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * This class is an extension to the standard math library - * provided by java.lang.Math class. It follows the Math class - * in that it has a private constructor and all static methods. - */ -public final class MathX { - - - private MathX() {} - - - /** - * 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 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 0) { - product = 1; - for (int i=0, iSize=values.length; i - * When n and s are "valid" arguments, the returned value is: Math.floor(n/s) * s; - *
    - * n and s are invalid if any of following conditions are true: - *

      - *
    • s is zero
    • - *
    • n is negative and s is positive
    • - *
    • n is positive and s is negative
    • - *
    - * 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(..). - *

    - * When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s; - *
    - * n and s are invalid if any of following conditions are true: - *

      - *
    • s is zero
    • - *
    • n is negative and s is positive
    • - *
    • n is positive and s is negative
    • - *
    - * 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: - *
      - *
    • mod(3.4, 2) = 1.4
    • - *
    • mod(-3.4, 2) = 0.6
    • - *
    • mod(-3.4, -2) = -1.4
    • - *
    • mod(3.4, -2) = -0.6
    • - *
    - * 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)) { - double t = Math.abs(n / d); - t = t - (long) t; - result = sign(d) * Math.abs(t * d); - } - else { - double t = Math.abs(n / d); - t = t - (long) t; - t = Math.ceil(t) - t; - result = sign(d) * Math.abs(t * 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) { - double d2 = d*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); - d = (ePowX + ePowNegX) / 2; - return d; - } - - /** - * hyperbolic sine - * @param d - */ - public static double sinh(double d) { - double ePowX = Math.pow(Math.E, d); - double ePowNegX = Math.pow(Math.E, -d); - d = (ePowX - ePowNegX) / 2; - return d; - } - - /** - * hyperbolic tangent - * @param d - */ - public static double tanh(double d) { - double ePowX = Math.pow(Math.E, d); - double ePowNegX = Math.pow(Math.E, -d); - d = (ePowX - ePowNegX) / (ePowX + ePowNegX); - return d; - } - - /** - * returns the sum of product of corresponding double value in each - * subarray. It is the responsibility of the caller to ensure that - * all the subarrays are of equal length. If the subarrays are - * not of equal length, the return value can be unpredictable. - * @param arrays - */ - public static double sumproduct(double[][] arrays) { - double d = 0; - - try { - int narr = arrays.length; - int arrlen = arrays[0].length; - - for (int j=0; j - * It is the responsibility of the caller - * to ensure that the two subarrays are of equal length. If the - * subarrays are not of equal length, the return value can be - * unpredictable. - * @param xarr - * @param yarr - */ - public static double sumx2my2(double[] xarr, double[] yarr) { - double d = 0; - - try { - for (int i=0, iSize=xarr.length; i - * It is the responsibility of the caller - * to ensure that the two subarrays are of equal length. If the - * subarrays are not of equal length, the return value can be - * unpredictable. - * @param xarr - * @param yarr - */ - public static double sumx2py2(double[] xarr, double[] yarr) { - double d = 0; - - try { - for (int i=0, iSize=xarr.length; i - * It is the responsibility of the caller - * to ensure that the two subarrays are of equal length. If the - * subarrays are not of equal length, the return value can be - * unpredictable. - * @param xarr - * @param yarr - */ - public static double sumxmy2(double[] xarr, double[] yarr) { - double d = 0; - - try { - for (int i=0, iSize=xarr.length; i 0 ? MathX.max(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java deleted file mode 100644 index e25db7b746..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Maxa.java +++ /dev/null @@ -1,66 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public final class Maxa extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - | ValueEvalToNumericXlator.BLANK_IS_PARSED - | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.max(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mdeterm.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mdeterm.java deleted file mode 100644 index ab57658c6d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mdeterm.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Mdeterm extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Median.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Median.java deleted file mode 100644 index 57a18b3314..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Median.java +++ /dev/null @@ -1,77 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Median extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) (0 - | ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.BLANK_IS_PARSED - )); - - /** - * this is the default impl for the factory method getXlator - * of the super class NumericFunction. Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = StatsLib.median(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mid.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mid.java deleted file mode 100644 index 7f30aa4cec..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mid.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.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.EvaluationException; -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; - -/** - * An implementation of the MID function
    MID returns a specific number of - * characters from a text string, starting at the specified position.

    - * - * Syntax:
    MID(text, start_num, - * num_chars)
    - * - * @author Manda Wilson < wilson at c bio dot msk cc dot org > - */ -public class Mid implements Function { - /** - * Returns a specific number of characters from a text string, starting at - * the position you specify, based on the number of characters you specify. - * - * @see org.apache.poi.hssf.record.formula.eval.Eval - */ - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - if (args.length != 3) { - return ErrorEval.VALUE_INVALID; - } - - String text; - int startIx; // zero based - int numChars; - - try { - ValueEval evText = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - text = OperandResolver.coerceValueToString(evText); - int startCharNum = evaluateNumberArg(args[1], srcCellRow, srcCellCol); - numChars = evaluateNumberArg(args[2], srcCellRow, srcCellCol); - startIx = startCharNum - 1; // convert to zero-based - } catch (EvaluationException e) { - return e.getErrorEval(); - } - - int len = text.length(); - if (startIx < 0) { - return ErrorEval.VALUE_INVALID; - } - if (numChars < 0) { - return ErrorEval.VALUE_INVALID; - } - if (numChars < 0 || startIx > len) { - return new StringEval(""); - } - int endIx = startIx + numChars; - if (endIx > len) { - endIx = len; - } - String result = text.substring(startIx, endIx); - return new StringEval(result); - - } - - private static int evaluateNumberArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException { - ValueEval ev = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol); - if (ev instanceof BlankEval) { - // Note - for start_num arg, blank causes error(#VALUE!), - // but for num_chars causes empty string to be returned. - return 0; - } - - return OperandResolver.coerceValueToInt(ev); - } -} \ No newline at end of file diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Midb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Midb.java deleted file mode 100644 index 2a06e4e09a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Midb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Midb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Min.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Min.java deleted file mode 100644 index 8cd896783c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Min.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Min extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.min(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java deleted file mode 100644 index 21ba47b569..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mina.java +++ /dev/null @@ -1,66 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Mina extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - | ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - | ValueEvalToNumericXlator.BLANK_IS_PARSED - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.min(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Minute.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Minute.java deleted file mode 100644 index a8b6836208..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Minute.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Minute extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Minverse.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Minverse.java deleted file mode 100644 index 66f5647b7e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Minverse.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Minverse extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mirr.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mirr.java deleted file mode 100644 index c87d11307d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mirr.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Mirr extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mmult.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mmult.java deleted file mode 100644 index 95a4bf2f70..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mmult.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Mmult extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mod.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mod.java deleted file mode 100644 index ebef231544..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mod.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Mod extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d0 = 0; - double d1 = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d0 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - if (retval == null) { - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d1 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - if (d1 == 0) { - retval = ErrorEval.DIV_ZERO; - } - else { - double d = MathX.mod(d0, d1); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mode.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mode.java deleted file mode 100644 index 724b6e6543..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Mode.java +++ /dev/null @@ -1,78 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Mode extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) (0 - //| ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.BLANK_IS_PARSED - )); - - /** - * this is the default impl for the factory method getXlator - * of the super class NumericFunction. Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = StatsLib.mode(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Month.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Month.java deleted file mode 100644 index d5178b22df..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Month.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.usermodel.HSSFDateUtil; - -/** - * - * @author Guenter Kickinger g.kickinger@gmx.net - * - */ -public class Month extends NumericFunction { - - /* (non-Javadoc) - * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) - */ - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { - java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem - retval = new NumberEval(d.getMonth()+1); - } else { - retval = ErrorEval.NUM_ERROR; - } - } - else if (ve instanceof BlankEval) { - // do nothing - } else { - retval = ErrorEval.NUM_ERROR; - } - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java deleted file mode 100644 index 0e7cce217e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/MultiOperandNumericFunction.java +++ /dev/null @@ -1,202 +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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.Ref2DEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * This is the super class for all excel function evaluator - * classes that take variable number of operands, and - * where the order of operands does not matter - */ -public abstract class MultiOperandNumericFunction extends NumericFunction { - static final double[] EMPTY_DOUBLE_ARRAY = { }; - - private static class DoubleList { - private double[] _array; - private int _count; - - public DoubleList() { - _array = new double[8]; - _count = 0; - } - - public double[] toArray() { - if(_count < 1) { - return EMPTY_DOUBLE_ARRAY; - } - double[] result = new double[_count]; - System.arraycopy(_array, 0, result, 0, _count); - return result; - } - - public void add(double[] values) { - int addLen = values.length; - ensureCapacity(_count + addLen); - System.arraycopy(values, 0, _array, _count, addLen); - _count += addLen; - } - - private void ensureCapacity(int reqSize) { - if(reqSize > _array.length) { - int newSize = reqSize * 3 / 2; // grow with 50% extra - double[] newArr = new double[newSize]; - System.arraycopy(_array, 0, newArr, 0, _count); - _array = newArr; - } - } - - public void add(double value) { - ensureCapacity(_count + 1); - _array[_count] = value; - _count++; - } - } - - private static final int DEFAULT_MAX_NUM_OPERANDS = 30; - - protected abstract ValueEvalToNumericXlator getXlator(); - - /** - * Maximum number of operands accepted by this function. - * Subclasses may override to change default value. - */ - protected int getMaxNumOperands() { - return DEFAULT_MAX_NUM_OPERANDS; - } - - /** - * Returns a double array that contains values for the numeric cells - * from among the list of operands. Blanks and Blank equivalent cells - * are ignored. Error operands or cells containing operands of type - * that are considered invalid and would result in #VALUE! error in - * excel cause this function to return null. - * - * @param operands - * @param srcRow - * @param srcCol - */ - protected double[] getNumberArray(Eval[] operands, int srcRow, short srcCol) { - if (operands.length > getMaxNumOperands()) { - return null; - } - DoubleList retval = new DoubleList(); - - for (int i=0, iSize=operands.length; ifalse if any sub-array is missing, or is of different length - */ - protected static final boolean areSubArraysConsistent(double[][] values) { - - if (values == null || values.length < 1) { - // TODO this doesn't seem right. Fix or add comment. - return true; - } - - if (values[0] == null) { - return false; - } - int outerMax = values.length; - int innerMax = values[0].length; - for (int i=1; i 'number is non-zero' - */ -public class Not extends BooleanFunction { - - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - boolean b = true; - ValueEval tempVe = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - if (operands[0] instanceof AreaEval) { - AreaEval ae = (AreaEval) operands[0]; - if (ae.isRow() && ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - tempVe = singleOperandEvaluate(ve); - } else if (ae.isColumn() && ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - tempVe = singleOperandEvaluate(ve); - } else { - retval = ErrorEval.VALUE_INVALID; - } - } - else { - tempVe = singleOperandEvaluate(operands[0]); - if (tempVe instanceof StringEval) { - retval = ErrorEval.VALUE_INVALID; - } - else if (tempVe instanceof ErrorEval) { - retval = tempVe; - } - } - } - - if (retval == null) { // if no error - if (tempVe instanceof BoolEval) { - b = b && ((BoolEval) tempVe).getBooleanValue(); - } - else if (tempVe instanceof StringEval) { - retval = ErrorEval.VALUE_INVALID; - } - else if (tempVe instanceof ErrorEval) { - retval = tempVe; - } - retval = b ? BoolEval.FALSE : BoolEval.TRUE; - } - - return retval; - } - - - protected ValueEval singleOperandEvaluate(Eval ve) { - ValueEval retval = ErrorEval.VALUE_INVALID; - if (ve instanceof RefEval) { - RefEval re = (RefEval) ve; - retval = singleOperandEvaluate(re.getInnerValueEval()); - } - else if (ve instanceof BoolEval) { - retval = (BoolEval) ve; - } - else if (ve instanceof NumberEval) { - NumberEval ne = (NumberEval) ve; - retval = ne.getNumberValue() != 0 ? BoolEval.TRUE : BoolEval.FALSE; - } - else if (ve instanceof StringEval) { - StringEval se = (StringEval) ve; - String str = se.getStringValue(); - retval = str.equalsIgnoreCase("true") - ? BoolEval.TRUE - : str.equalsIgnoreCase("false") - ? BoolEval.FALSE - : (ValueEval) ErrorEval.VALUE_INVALID; - } - else if (ve instanceof BlankEval) { - retval = BoolEval.FALSE; - } - else { - retval = ErrorEval.VALUE_INVALID; - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java deleted file mode 100644 index 49ed84fb46..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NotImplementedFunction.java +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; - -/** - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * This is the default implementation of a Function class. - * The default behaviour is to return a non-standard ErrorEval - * "ErrorEval.FUNCTION_NOT_IMPLEMENTED". This error should alert - * the user that the formula contained a function that is not - * yet implemented. - */ -public class NotImplementedFunction implements Function { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - return ErrorEval.FUNCTION_NOT_IMPLEMENTED; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Note.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Note.java deleted file mode 100644 index 210770ad71..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Note.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Note extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Now.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Now.java deleted file mode 100644 index 2c23a97b37..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Now.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Now extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Nper.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Nper.java deleted file mode 100644 index 95411edb77..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Nper.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. -*/ -/* - * Created on May 15, 2005 - * - */ -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Nper extends FinanceFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double rate = 0, fv = 0, pmt = 0, pv = 0, d = 0; - boolean type = false; - ValueEval retval = null; - ValueEval ve = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 5: - ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol); - if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; } - type = ((BoolEval) ve).getBooleanValue(); - case 4: - ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - - ve = singleOperandEvaluate(operands[2], srcRow, srcCol); - if (ve instanceof NumericValueEval) pv = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - - ve = singleOperandEvaluate(operands[3], srcRow, srcCol); - if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - } - - if (retval == null) { - d = FinanceLib.nper(rate, pmt, pv, fv, type); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : (Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Npv.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Npv.java deleted file mode 100644 index 9e57999d76..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Npv.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Npv extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Numberstring.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Numberstring.java deleted file mode 100644 index 51403415cd..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Numberstring.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Numberstring extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java deleted file mode 100644 index fd96f1495a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/NumericFunction.java +++ /dev/null @@ -1,98 +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 14, 2005 - * - */ -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.Eval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class NumericFunction implements Function { - - protected static final double E = Math.E; - protected static final double PI = Math.PI; - - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - | ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - | ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - )); - - private static final int DEFAULT_MAX_NUM_OPERANDS = 30; - - /** - * this is the default impl of the factory(ish) method getXlator. - * Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { - ValueEval retval; - if (eval instanceof AreaEval) { - AreaEval ae = (AreaEval) eval; - if (ae.contains(srcRow, srcCol)) { // circular ref! - retval = ErrorEval.CIRCULAR_REF_ERROR; - } - else if (ae.isRow()) { - if (ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - ve = getXlator().attemptXlateToNumeric(ve); - retval = getXlator().attemptXlateToNumeric(ve); - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - retval = getXlator().attemptXlateToNumeric(ve); - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else { - retval = getXlator().attemptXlateToNumeric((ValueEval) eval); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Odd.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Odd.java deleted file mode 100644 index 8af68c3db5..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Odd.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 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Odd extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - if (!Double.isNaN(d) && !Double.isInfinite(d)) { - d = (d==0) - ? 1 - : ((((long) d) - 1) % 2 == 0) - ? d - : (d < 0) - ? ((((long) (d/2))<<1)-1) - : ((((long) (d/2))<<1)+1); - } - retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Offset.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Offset.java deleted file mode 100644 index 9497a5f21a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Offset.java +++ /dev/null @@ -1,362 +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.Area3DPtg; -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.eval.Area3DEval; -import org.apache.poi.hssf.record.formula.eval.AreaEval; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.Ref3DEval; -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; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -/** - * Implementation for Excel function OFFSET()

    - * - * OFFSET returns an area reference that is a specified number of rows and columns from a - * reference cell or area.

    - * - * Syntax:
    - * 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 FreeRefFunction { - // These values are specific to BIFF8 - private static final int LAST_VALID_ROW_INDEX = 0xFFFF; - private static final int LAST_VALID_COLUMN_INDEX = 0xFF; - - - /** - * Exceptions are used within this class to help simplify flow control when error conditions - * are encountered - */ - private static final class EvalEx extends Exception { - private final ErrorEval _error; - - public EvalEx(ErrorEval error) { - _error = error; - } - public ErrorEval getError() { - return _error; - } - } - - /** - * 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 static final int INVALID_SHEET_INDEX = -1; - private final int _firstRowIndex; - private final int _firstColumnIndex; - private final int _width; - private final int _height; - private final int _externalSheetIndex; - - public BaseRef(RefEval re) { - _firstRowIndex = re.getRow(); - _firstColumnIndex = re.getColumn(); - _height = 1; - _width = 1; - if (re instanceof Ref3DEval) { - Ref3DEval r3e = (Ref3DEval) re; - _externalSheetIndex = r3e.getExternSheetIndex(); - } else { - _externalSheetIndex = INVALID_SHEET_INDEX; - } - } - - public BaseRef(AreaEval ae) { - _firstRowIndex = ae.getFirstRow(); - _firstColumnIndex = ae.getFirstColumn(); - _height = ae.getLastRow() - ae.getFirstRow() + 1; - _width = ae.getLastColumn() - ae.getFirstColumn() + 1; - if (ae instanceof Area3DEval) { - Area3DEval a3e = (Area3DEval) ae; - _externalSheetIndex = a3e.getExternSheetIndex(); - } else { - _externalSheetIndex = INVALID_SHEET_INDEX; - } - } - - public int getWidth() { - return _width; - } - - public int getHeight() { - return _height; - } - - public int getFirstRowIndex() { - return _firstRowIndex; - } - - public int getFirstColumnIndex() { - return _firstColumnIndex; - } - - public boolean isIs3d() { - return _externalSheetIndex > 0; - } - - public short getExternalSheetIndex() { - if(_externalSheetIndex < 0) { - throw new IllegalStateException("external sheet index only available for 3d refs"); - } - return (short) _externalSheetIndex; - } - - } - - public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) { - - 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, workbook, sheet); - } catch (EvalEx e) { - return e.getError(); - } - } - - - private static AreaEval createOffset(BaseRef baseRef, - LinearOffsetRange rowOffsetRange, LinearOffsetRange colOffsetRange, - HSSFWorkbook workbook, HSSFSheet sheet) throws EvalEx { - - LinearOffsetRange rows = rowOffsetRange.normaliseAndTranslate(baseRef.getFirstRowIndex()); - LinearOffsetRange cols = colOffsetRange.normaliseAndTranslate(baseRef.getFirstColumnIndex()); - - if(rows.isOutOfBounds(0, LAST_VALID_ROW_INDEX)) { - throw new EvalEx(ErrorEval.REF_INVALID); - } - if(cols.isOutOfBounds(0, LAST_VALID_COLUMN_INDEX)) { - throw new EvalEx(ErrorEval.REF_INVALID); - } - if(baseRef.isIs3d()) { - Area3DPtg a3dp = new Area3DPtg(rows.getFirstIndex(), rows.getLastIndex(), - cols.getFirstIndex(), cols.getLastIndex(), - false, false, false, false, - baseRef.getExternalSheetIndex()); - return HSSFFormulaEvaluator.evaluateArea3dPtg(workbook, a3dp); - } - - AreaPtg ap = new AreaPtg(rows.getFirstIndex(), rows.getLastIndex(), - cols.getFirstIndex(), cols.getLastIndex(), - false, false, false, false); - return HSSFFormulaEvaluator.evaluateAreaPtg(sheet, workbook, ap); - } - - - private static BaseRef evaluateBaseRef(Eval eval) throws EvalEx { - - if(eval instanceof RefEval) { - return new BaseRef((RefEval)eval); - } - if(eval instanceof AreaEval) { - return new BaseRef((AreaEval)eval); - } - if (eval instanceof ErrorEval) { - throw new EvalEx((ErrorEval) eval); - } - throw new EvalEx(ErrorEval.VALUE_INVALID); - } - - - /** - * OFFSET's numeric arguments (2..5) have similar processing rules - */ - private static int evaluateIntArg(Eval eval, int srcCellRow, short srcCellCol) throws EvalEx { - - double d = evaluateDoubleArg(eval, srcCellRow, srcCellCol); - return convertDoubleToInt(d); - } - - /** - * Fractional values are silently truncated by Excel. - * Truncation is toward negative infinity. - */ - /* package */ static int convertDoubleToInt(double d) { - // 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); - } - - - private static double evaluateDoubleArg(Eval eval, int srcCellRow, short srcCellCol) throws EvalEx { - ValueEval ve = evaluateSingleValue(eval, srcCellRow, srcCellCol); - - if (ve instanceof NumericValueEval) { - return ((NumericValueEval) ve).getNumberValue(); - } - if (ve instanceof StringEval) { - StringEval se = (StringEval) ve; - Double d = parseDouble(se.getStringValue()); - if(d == null) { - throw new EvalEx(ErrorEval.VALUE_INVALID); - } - return d.doubleValue(); - } - if (ve instanceof BoolEval) { - // in the context of OFFSET, booleans resolve to 0 and 1. - if(((BoolEval) ve).getBooleanValue()) { - return 1; - } - return 0; - } - throw new RuntimeException("Unexpected eval type (" + ve.getClass().getName() + ")"); - } - - private static Double parseDouble(String s) { - // TODO - find a home for this method - // TODO - support various number formats: sign char, dollars, commas - // OFFSET and COUNTIF seem to handle these - return Countif.parseDouble(s); - } - - private static ValueEval evaluateSingleValue(Eval eval, int srcCellRow, short srcCellCol) throws EvalEx { - if(eval instanceof RefEval) { - return ((RefEval)eval).getInnerValueEval(); - } - if(eval instanceof AreaEval) { - return chooseSingleElementFromArea((AreaEval)eval, srcCellRow, srcCellCol); - } - if (eval instanceof ValueEval) { - return (ValueEval) eval; - } - throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")"); - } - - // TODO - this code seems to get repeated a bit - private static ValueEval chooseSingleElementFromArea(AreaEval ae, int srcCellRow, short srcCellCol) throws EvalEx { - if (ae.isColumn()) { - if (ae.isRow()) { - return ae.getValues()[0]; - } - if (!ae.containsRow(srcCellRow)) { - throw new EvalEx(ErrorEval.VALUE_INVALID); - } - return ae.getValueAt(srcCellRow, ae.getFirstColumn()); - } - if (!ae.isRow()) { - throw new EvalEx(ErrorEval.VALUE_INVALID); - } - if (!ae.containsColumn(srcCellCol)) { - throw new EvalEx(ErrorEval.VALUE_INVALID); - } - return ae.getValueAt(ae.getFirstRow(), srcCellCol); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Or.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Or.java deleted file mode 100644 index 22d7003d4d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Or.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. -*/ -/* - * Created on May 9, 2005 - * - */ -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.BoolEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Or extends BooleanFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval = null; - boolean b = false; - boolean atleastOneNonBlank = false; - - /* - * Note: do not abort the loop if b is true, since we could be - * dealing with errorevals later. - */ - outer: - for (int i=0, iSize=operands.length; i - * - * Syntax:
    - * PMT(rate, nper, pv, fv, type)

    - * - * Returns the constant repayment amount required for a loan assuming a constant interest rate.

    - * - * rate the loan interest rate.
    - * nper the number of loan repayments.
    - * pv the present value of the future payments (or principle).
    - * fv the future value (default zero) surplus cash at the end of the loan lifetime.
    - * type whether payments are due at the beginning(1) or end(0 - default) of each payment period.
    - * - */ -public final class Pmt extends FinanceFunction { - - public Eval evaluate(Eval[] args, int srcRow, short srcCol) { - - if(args.length < 3 || args.length > 5) { - return ErrorEval.VALUE_INVALID; - } - - try { - // evaluate first three (always present) args - double rate = evalArg(args[0], srcRow, srcCol); - double nper = evalArg(args[1], srcRow, srcCol); - double pv = evalArg(args[2], srcRow, srcCol); - double fv = 0; - boolean arePaymentsAtPeriodBeginning = false; - - switch (args.length) { - case 5: - ValueEval ve = singleOperandNumericAsBoolean(args[4], srcRow, srcCol); - if (ve instanceof ErrorEval) { - return ve; - } - arePaymentsAtPeriodBeginning = ((BoolEval) ve).getBooleanValue(); - case 4: - fv = evalArg(args[3], srcRow, srcCol); - } - double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning); - if (Double.isNaN(d)) { - return (ValueEval) ErrorEval.VALUE_INVALID; - } - if (Double.isInfinite(d)) { - return (ValueEval) ErrorEval.NUM_ERROR; - } - return new NumberEval(d); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - private double evalArg(Eval arg, int srcRow, short srcCol) throws EvaluationException { - ValueEval ve = singleOperandEvaluate(arg, srcRow, srcCol); - if(ve instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) ve); - } - if (ve instanceof NumericValueEval) { - return ((NumericValueEval) ve).getNumberValue(); - } - throw new EvaluationException(ErrorEval.VALUE_INVALID); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Poisson.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Poisson.java deleted file mode 100644 index f4aba4c7f1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Poisson.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Poisson extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Power.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Power.java deleted file mode 100644 index 1327e80061..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Power.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. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Power extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d0 = 0; - double d1 = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d0 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - if (retval == null) { - ValueEval vev = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (vev instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) vev; - d1 = ne.getNumberValue(); - } - else if (vev instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - double d = Math.pow(d0, d1); - retval = (Double.isNaN(d) || Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ppmt.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ppmt.java deleted file mode 100644 index 4e36630b94..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ppmt.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Ppmt extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Prob.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Prob.java deleted file mode 100644 index 12293687f1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Prob.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Prob extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Product.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Product.java deleted file mode 100644 index a88a3245d6..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Product.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Product extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = MathX.product(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Proper.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Proper.java deleted file mode 100644 index 26a8c3a90a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Proper.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Proper extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Pv.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Pv.java deleted file mode 100644 index 1d54bee93d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Pv.java +++ /dev/null @@ -1,74 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Pv extends FinanceFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double rate = 0, fv = 0, nper = 0, pmt = 0, d = 0; - boolean type = false; - ValueEval retval = null; - ValueEval ve = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 5: - ve = singleOperandNumericAsBoolean(operands[4], srcRow, srcCol); - if (ve instanceof ErrorEval) { retval = ErrorEval.VALUE_INVALID; break; } - type = ((BoolEval) ve).getBooleanValue(); - case 4: - ve = singleOperandEvaluate(operands[3], srcRow, srcCol); - if (ve instanceof NumericValueEval) fv = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - case 3: - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) nper = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - - ve = singleOperandEvaluate(operands[2], srcRow, srcCol); - if (ve instanceof NumericValueEval) pmt = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - - ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) rate = ((NumericValueEval) ve).getNumberValue(); - else { retval = ErrorEval.VALUE_INVALID; break; } - } - - if (retval == null) { - d = FinanceLib.pv(rate, nper, pmt, fv, type); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : (Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Quartile.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Quartile.java deleted file mode 100644 index ec81094f1f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Quartile.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Quartile extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Radians.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Radians.java deleted file mode 100644 index 836fab3ad1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Radians.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Radians extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.toRadians(d); - retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rand.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rand.java deleted file mode 100644 index 4c180383d8..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rand.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. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Rand implements Function { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval; - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 0: - retval = new NumberEval(Math.random()); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rank.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rank.java deleted file mode 100644 index 2bb13d3fec..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rank.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Rank extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rate.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rate.java deleted file mode 100644 index 485920c751..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rate.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Rate extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Reftext.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Reftext.java deleted file mode 100644 index 3ba7bc988a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Reftext.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Reftext extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Relref.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Relref.java deleted file mode 100644 index 7e7bee8df8..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Relref.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Relref extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Replace.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Replace.java deleted file mode 100644 index 95413f0823..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Replace.java +++ /dev/null @@ -1,112 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.StringValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * An implementation of the REPLACE function: - * Replaces part of a text string based on the number of characters - * you specify, with another text string. - * @author Manda Wilson < wilson at c bio dot msk cc dot org > - */ -public class Replace extends TextFunction { - - /** - * Replaces part of a text string based on the number of characters - * you specify, with another text string. - * - * @see org.apache.poi.hssf.record.formula.eval.Eval - */ - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = null; - String oldStr = null; - String newStr = null; - int startNum = 0; - int numChars = 0; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - case 4: - // first operand is text string containing characters to replace - // second operand is position of first character to replace - // third operand is the number of characters in the old string - // you want to replace with new string - // fourth operand is the new string - ValueEval firstveval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - ValueEval secondveval = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); - ValueEval thirdveval = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol); - ValueEval fourthveval = singleOperandEvaluate(operands[3], srcCellRow, srcCellCol); - if (firstveval instanceof StringValueEval - && secondveval instanceof NumericValueEval - && thirdveval instanceof NumericValueEval - && fourthveval instanceof StringValueEval) { - - StringValueEval oldStrEval = (StringValueEval) firstveval; - oldStr = oldStrEval.getStringValue(); - - NumericValueEval startNumEval = (NumericValueEval) secondveval; - // NOTE: it is safe to cast to int here - // because in Excel =REPLACE("task", 2.7, 3, "est") - // returns test - // so 2.7 must be truncated to 2 - // and =REPLACE("task", 1, 1.9, "") returns ask - // so 1.9 must be truncated to 1 - startNum = (int) startNumEval.getNumberValue(); - - NumericValueEval numCharsEval = (NumericValueEval) thirdveval; - numChars = (int) numCharsEval.getNumberValue(); - - StringValueEval newStrEval = (StringValueEval) fourthveval; - newStr = newStrEval.getStringValue(); - } else { - retval = ErrorEval.VALUE_INVALID; - } - } - - if (retval == null) { - if (startNum < 1 || numChars < 0) { - retval = ErrorEval.VALUE_INVALID; - } else { - 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); - } - retval = new StringEval(strBuff.toString()); - } - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Replaceb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Replaceb.java deleted file mode 100644 index 93d05bf083..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Replaceb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Replaceb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rept.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rept.java deleted file mode 100644 index ce56e70d9d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rept.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Rept extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Request.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Request.java deleted file mode 100644 index 23eeea5ce0..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Request.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Request extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Result.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Result.java deleted file mode 100644 index c15f2421e1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Result.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Result extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Right.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Right.java deleted file mode 100644 index 771d045734..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Right.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. -*/ -/* - * Created on May 15, 2005 - * - */ -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.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 > - * - */ -public class Right extends TextFunction { - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = ErrorEval.VALUE_INVALID; - int index = 1; - switch (operands.length) { - default: - break; - case 2: - Eval indexEval = operands[1]; - index = evaluateAsInteger(indexEval); - if (index < 0) { - break; - } - case 1: - ValueEval veval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - String str = null; - if (veval instanceof StringEval) { - StringEval stringEval = (StringEval) veval; - str = stringEval.getStringValue(); - } - else if (veval instanceof BoolEval) { - BoolEval beval = (BoolEval) veval; - str = beval.getBooleanValue() ? "TRUE" : "FALSE"; - } - else if (veval instanceof NumberEval) { - NumberEval neval = (NumberEval) veval; - str = neval.getStringValue(); - } - if (null != str) { - int strlen = str.length(); - str = str.substring(Math.max(0, strlen-index)); - retval = new StringEval(str); - } - } - return retval; - } - - protected int evaluateAsInteger(Eval eval) { - int numval = -1; - if (eval instanceof NumberEval) { - NumberEval neval = (NumberEval) eval; - double d = neval.getNumberValue(); - numval = (int) d; - } - else if (eval instanceof StringEval) { - StringEval seval = (StringEval) eval; - String s = seval.getStringValue(); - try { - double d = Double.parseDouble(s); - numval = (int) d; - } - catch (Exception e) { - } - } - else if (eval instanceof BoolEval) { - BoolEval beval = (BoolEval) eval; - numval = beval.getBooleanValue() ? 1 : 0; - } - else if (eval instanceof RefEval) { - numval = evaluateAsInteger(xlateRefEval((RefEval) eval)); - } - return numval; - } - - protected Eval xlateRefEval(RefEval reval) { - Eval retval = reval.getInnerValueEval(); - - if (retval instanceof RefEval) { - retval = xlateRefEval((RefEval) retval); - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rightb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rightb.java deleted file mode 100644 index 4ee99fdf04..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rightb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Rightb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Roman.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Roman.java deleted file mode 100644 index c2db7e86c6..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Roman.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Roman extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Round.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Round.java deleted file mode 100644 index db4f1db0ee..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Round.java +++ /dev/null @@ -1,83 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Round extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d0 = 0; - double d1 = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d0 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - if (retval == null) { - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d1 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - double d; - if (d0 > Integer.MAX_VALUE) { - d = (Double.isNaN(d0) || Double.isInfinite(d0)) - ? Double.NaN - : 0; - } - else { - d = MathX.round(d0, (int) d1); - } - retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rounddown.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rounddown.java deleted file mode 100644 index 13522294fd..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rounddown.java +++ /dev/null @@ -1,86 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Rounddown extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d0 = 0; - double d1 = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if(ve instanceof ErrorEval) { - return ve; - } - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d0 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - if (retval == null) { - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d1 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - double d; - if (d0 > Integer.MAX_VALUE) { - d = (Double.isInfinite(d0)) - ? Double.NaN - : 0; - } - else { - d = MathX.roundDown(d0, (int) d1); - } - retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d); - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Roundup.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Roundup.java deleted file mode 100644 index 4dae76d981..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Roundup.java +++ /dev/null @@ -1,88 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Roundup extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d0 = 0; - double d1 = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 2: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if(ve instanceof ErrorEval) { - return ve; - } - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d0 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - - if (retval == null) { - ve = singleOperandEvaluate(operands[1], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d1 = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - } - - if (retval == null) { - double d; - if (d0 > Integer.MAX_VALUE) { - d = (Double.isNaN(d0)) - ? Double.NaN - : 0; - } - else { - d = MathX.roundUp(d0, (int) d1); - } - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Row.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Row.java deleted file mode 100644 index d111d594b5..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Row.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -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.Eval; -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; - -public class Row implements Function { - - public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - int rnum = -1; - - switch (evals.length) { - default: - retval = ErrorEval.VALUE_INVALID; - case 1: - if (evals[0] instanceof AreaEval) { - AreaEval ae = (AreaEval) evals[0]; - rnum = ae.getFirstRow(); - } - else if (evals[0] instanceof RefEval) { - RefEval re = (RefEval) evals[0]; - rnum = re.getRow(); - } - else { // anything else is not valid argument - retval = ErrorEval.VALUE_INVALID; - } - break; - case 0: - rnum = srcCellRow; - } - - if (retval == null) { - retval = (rnum >= 0) - ? new NumberEval(rnum + 1) // +1 since excel rownums are 1 based - : (ValueEval) ErrorEval.VALUE_INVALID; - } - - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rows.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rows.java deleted file mode 100644 index aabffab2f6..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rows.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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; - -/** - * Implementation for Excel ROWS function. - * - * @author Josh Micich - */ -public final class Rows implements Function { - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - switch(args.length) { - case 1: - // expected - break; - case 0: - // too few arguments - return ErrorEval.VALUE_INVALID; - default: - // too many arguments - return ErrorEval.VALUE_INVALID; - } - Eval firstArg = args[0]; - - int result; - if (firstArg instanceof AreaEval) { - AreaEval ae = (AreaEval) firstArg; - result = ae.getLastRow() - ae.getFirstRow() + 1; - } else if (firstArg instanceof RefEval) { - result = 1; - } else { // anything else is not valid argument - return ErrorEval.VALUE_INVALID; - } - return new NumberEval(result); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rsq.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rsq.java deleted file mode 100644 index f1addc391f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Rsq.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Rsq extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Search.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Search.java deleted file mode 100644 index 351495c6ce..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Search.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Search extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Searchb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Searchb.java deleted file mode 100644 index 3dfa711ab6..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Searchb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Searchb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Second.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Second.java deleted file mode 100644 index 3ebd5534a7..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Second.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Second extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Series.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Series.java deleted file mode 100644 index 3e60685936..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Series.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Series extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Setname.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Setname.java deleted file mode 100644 index 5f01782027..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Setname.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Setname extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Setvalue.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Setvalue.java deleted file mode 100644 index c86e65e80c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Setvalue.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Setvalue extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sign.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sign.java deleted file mode 100644 index 2353cf47f9..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sign.java +++ /dev/null @@ -1,62 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -public class Sign extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : new NumberEval(MathX.sign(d)); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sin.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sin.java deleted file mode 100644 index 1e7669302e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sin.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Sin extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.sin(d); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sinh.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sinh.java deleted file mode 100644 index 8b03502865..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sinh.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Sinh extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = MathX.sinh(d); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Skew.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Skew.java deleted file mode 100644 index bb6d259fb0..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Skew.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Skew extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sln.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sln.java deleted file mode 100644 index dfb81768c4..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sln.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Sln extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Slope.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Slope.java deleted file mode 100644 index fb631f5649..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Slope.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Slope extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Small.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Small.java deleted file mode 100644 index 9fcdc1045e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Small.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Small extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) (0 - | ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.EVALUATED_REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.BLANK_IS_PARSED - )); - - /** - * this is the default impl for the factory method getXlator - * of the super class NumericFunction. Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] ops = getNumberArray(operands, srcCellRow, srcCellCol); - if (ops == null || ops.length < 2) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double[] values = new double[ops.length-1]; - int k = (int) ops[ops.length-1]; - System.arraycopy(ops, 0, values, 0, values.length); - double d = StatsLib.kthSmallest(values, k); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sqrt.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sqrt.java deleted file mode 100644 index 57ce5cf48d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sqrt.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Sqrt extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.sqrt(d); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Standardize.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Standardize.java deleted file mode 100644 index 6fa1df51cf..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Standardize.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Standardize extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/StatsLib.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/StatsLib.java deleted file mode 100644 index 8ebccfd950..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/StatsLib.java +++ /dev/null @@ -1,170 +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 30, 2005 - * - */ -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 - */ -public final class StatsLib { - - private StatsLib() {} - - - /** - * 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 1) { - r = Math.sqrt( devsq(v) / (v.length - 1) ); - } - return r; - } - - /** - * if v is zero length or contains no duplicates, return value - * is Double.NaN. Else returns the value that occurs most times - * and if there is a tie, returns the first such value. - * @param v - */ - public static double mode(double[] v) { - double r = Double.NaN; - - // very naive impl, may need to be optimized - if (v!=null && v.length > 1) { - int[] counts = new int[v.length]; - Arrays.fill(counts, 1); - for (int i=0, iSize=v.length; i maxc) { - maxv = v[i]; - maxc = counts[i]; - } - } - r = (maxc > 1) ? maxv : Double.NaN; // "no-dups" check - } - return r; - } - - public static double median(double[] v) { - double r = Double.NaN; - - if (v!=null && v.length >= 1) { - int n = v.length; - Arrays.sort(v); - r = (n % 2 == 0) - ? (v[n / 2] + v[n / 2 - 1]) / 2 - : v[n / 2]; - } - - return r; - } - - - public static double devsq(double[] v) { - double r = Double.NaN; - if (v!=null && v.length >= 1) { - double m = 0; - double s = 0; - int n = v.length; - for (int i=0; i - * k <= 0 & k >= v.length and null or empty arrays - * will result in return value Double.NaN - * @param v - * @param k - */ - public static double kthLargest(double[] v, int k) { - double r = Double.NaN; - k--; // since arrays are 0-based - if (v!=null && v.length > k && k >= 0) { - Arrays.sort(v); - r = v[v.length-k-1]; - } - return r; - } - - /** - * returns the kth smallest element in the array. Duplicates - * are considered as distinct values. Hence, eg. - * for array {1,1,2,4,3,3} & k=2, returned value is 1. - *
    - * 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; - k--; // since arrays are 0-based - if (v!=null && v.length > k && k >= 0) { - Arrays.sort(v); - r = v[k]; - } - return r; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java deleted file mode 100644 index 7995e66c34..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdev.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Stdev extends MultiOperandNumericFunction { - - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - )); - - /** - * this is the default impl for the factory method getXlator - * of the super class NumericFunction. Subclasses can override this method - * if they desire to return a different ValueEvalToNumericXlator instance - * than the default. - */ - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = StatsLib.stdev(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdeva.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdeva.java deleted file mode 100644 index 50306a2d69..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdeva.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Stdeva extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdevp.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdevp.java deleted file mode 100644 index c270c3c7f9..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdevp.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Stdevp extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdevpa.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdevpa.java deleted file mode 100644 index 2554b22014..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Stdevpa.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Stdevpa extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Step.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Step.java deleted file mode 100644 index 3febcca471..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Step.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Step extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Steyx.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Steyx.java deleted file mode 100644 index d92f3ef405..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Steyx.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Steyx extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Substitute.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Substitute.java deleted file mode 100644 index 9d2e9ce361..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Substitute.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.StringValueEval; -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 class Substitute extends TextFunction { - private static final int REPLACE_ALL = -1; - - /** - *Substitutes text in a text string with new text, some number of times. - * - * @see org.apache.poi.hssf.record.formula.eval.Eval - */ - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - Eval retval = null; - String oldStr = null; - String searchStr = null; - String newStr = null; - int numToReplace = REPLACE_ALL; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - case 4: - ValueEval fourthveval = singleOperandEvaluate(operands[3], srcCellRow, srcCellCol); - if (fourthveval instanceof NumericValueEval) { - NumericValueEval numToReplaceEval = (NumericValueEval) fourthveval; - // NOTE: it is safe to cast to int here - // because in Excel =SUBSTITUTE("teststr","t","T",1.9) - // returns Teststr - // so 1.9 must be truncated to 1 - numToReplace = (int) numToReplaceEval.getNumberValue(); - } else { - retval = ErrorEval.VALUE_INVALID; - } - case 3: - // first operand is text string containing characters to replace - // second operand is text to find - // third operand is replacement text - ValueEval firstveval = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - ValueEval secondveval = singleOperandEvaluate(operands[1], srcCellRow, srcCellCol); - ValueEval thirdveval = singleOperandEvaluate(operands[2], srcCellRow, srcCellCol); - if (firstveval instanceof StringValueEval - && secondveval instanceof StringValueEval - && thirdveval instanceof StringValueEval) { - - StringValueEval oldStrEval = (StringValueEval) firstveval; - oldStr = oldStrEval.getStringValue(); - - StringValueEval searchStrEval = (StringValueEval) secondveval; - searchStr = searchStrEval.getStringValue(); - - StringValueEval newStrEval = (StringValueEval) thirdveval; - newStr = newStrEval.getStringValue(); - } else { - retval = ErrorEval.VALUE_INVALID; - } - } - - if (retval == null) { - if (numToReplace != REPLACE_ALL && numToReplace < 1) { - retval = ErrorEval.VALUE_INVALID; - } else if (searchStr.length() == 0) { - retval = new StringEval(oldStr); - } else { - StringBuffer strBuff = new StringBuffer(); - int startIndex = 0; - int nextMatch = -1; - for (int leftToReplace = numToReplace; - (leftToReplace > 0 || numToReplace == REPLACE_ALL) - && (nextMatch = oldStr.indexOf(searchStr, startIndex)) != -1; - leftToReplace--) { - // store everything from end of last match to start of this match - strBuff.append(oldStr.substring(startIndex, nextMatch)); - strBuff.append(newStr); - startIndex = nextMatch + searchStr.length(); - } - // store everything from end of last match to end of string - if (startIndex < oldStr.length()) { - strBuff.append(oldStr.substring(startIndex)); - } - retval = new StringEval(strBuff.toString()); - } - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Subtotal.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Subtotal.java deleted file mode 100644 index ddfa3ad12a..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Subtotal.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Subtotal extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sum.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sum.java deleted file mode 100644 index d3dcd9b202..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sum.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Sum extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = values.length > 0 ? MathX.sum(values) : 0; - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumif.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumif.java deleted file mode 100644 index 11cb02315e..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumif.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Sumif extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumproduct.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumproduct.java deleted file mode 100644 index 9f6eafa4dc..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumproduct.java +++ /dev/null @@ -1,241 +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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - - -/** - * Implementation for the Excel function SUMPRODUCT

    - * - * Syntax :
    - * SUMPRODUCT ( array1[, array2[, array3[, ...]]]) - * - * - *
    array1, ... arrayN  typically area references, - * possibly cell references or scalar values

    - * - * Let An(i,j) represent the element in the ith row jth column - * of the nth array
    - * Assuming each array has the same dimensions (W, H), the result is defined as:
    - * SUMPRODUCT = Σi: 1..H   - * (  Σj: 1..W   - * (  Πn: 1..N - * An(i,j)  - * )  - * ) - * - * @author Josh Micich - */ -public final class Sumproduct implements Function { - - private static final class EvalEx extends Exception { - private final ErrorEval _error; - - public EvalEx(ErrorEval error) { - _error = error; - } - public ErrorEval getError() { - return _error; - } - } - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - - int maxN = args.length; - - if(maxN < 1) { - return ErrorEval.VALUE_INVALID; - } - Eval firstArg = args[0]; - try { - if(firstArg instanceof NumericValueEval) { - return evaluateSingleProduct(args); - } - if(firstArg instanceof RefEval) { - return evaluateSingleProduct(args); - } - if(firstArg instanceof AreaEval) { - AreaEval ae = (AreaEval) firstArg; - if(ae.isRow() && ae.isColumn()) { - return evaluateSingleProduct(args); - } - return evaluateAreaSumProduct(args); - } - } catch (EvalEx e) { - return e.getError(); - } - throw new RuntimeException("Invalid arg type for SUMPRODUCT: (" - + firstArg.getClass().getName() + ")"); - } - - private Eval evaluateSingleProduct(Eval[] evalArgs) throws EvalEx { - int maxN = evalArgs.length; - - double term = 1D; - for(int n=0; ndouble value for the specified ValueEval. - * @param isScalarProduct false for SUMPRODUCTs over area refs. - * @throws EvalEx 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 EvalEx { - - 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 EvalEx(ErrorEval.VALUE_INVALID); - } - return 0; - } - - if(ve instanceof ErrorEval) { - throw new EvalEx((ErrorEval)ve); - } - if(ve instanceof StringEval) { - if(isScalarProduct) { - throw new EvalEx(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/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java deleted file mode 100644 index b74b4161ac..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumsq.java +++ /dev/null @@ -1,70 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEvalToNumericXlator; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Sumsq extends MultiOperandNumericFunction { - private static final ValueEvalToNumericXlator DEFAULT_NUM_XLATOR = - new ValueEvalToNumericXlator((short) ( - ValueEvalToNumericXlator.BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_BOOL_IS_PARSED - | ValueEvalToNumericXlator.STRING_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.EVALUATED_REF_STRING_IS_PARSED - //| ValueEvalToNumericXlator.STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.REF_STRING_TO_BOOL_IS_PARSED - //| ValueEvalToNumericXlator.STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_STRING_IS_INVALID_VALUE - //| ValueEvalToNumericXlator.REF_BLANK_IS_PARSED - //| ValueEvalToNumericXlator.BLANK_IS_PARSED - )); - - protected ValueEvalToNumericXlator getXlator() { - return DEFAULT_NUM_XLATOR; - } - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - double[] values = getNumberArray(operands, srcCellRow, srcCellCol); - if (values == null) { - retval = ErrorEval.VALUE_INVALID; - } - else { - double d = MathX.sumsq(values); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.java deleted file mode 100644 index 30ad5ec230..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2my2.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.functions; - -/** - * Implementation of Excel function SUMX2MY2()

    - * - * Calculates the sum of differences of squares in two arrays of the same size.
    - * Syntax:
    - * SUMX2MY2(arrayX, arrayY)

    - * - * result = Σi: 0..n(xi2-yi2) - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class Sumx2my2 extends XYNumericFunction { - - protected double evaluate(double[] xArray, double[] yArray) { - return MathX.sumx2my2(xArray, yArray); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.java deleted file mode 100644 index dfd730d12c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumx2py2.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.functions; - -/** - * Implementation of Excel function SUMX2PY2()

    - * - * Calculates the sum of squares in two arrays of the same size.
    - * Syntax:
    - * SUMX2PY2(arrayX, arrayY)

    - * - * result = Σi: 0..n(xi2+yi2) - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class Sumx2py2 extends XYNumericFunction { - - protected double evaluate(double[] xArray, double[] yArray) { - return MathX.sumx2py2(xArray, yArray); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.java deleted file mode 100644 index a1b2fec9b2..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Sumxmy2.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.functions; - -/** - * Implementation of Excel function SUMXMY2()

    - * - * Calculates the sum of squares of differences between two arrays of the same size.
    - * Syntax:
    - * SUMXMY2(arrayX, arrayY)

    - * - * result = Σi: 0..n(xi-yi)2 - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class Sumxmy2 extends XYNumericFunction { - - protected double evaluate(double[] xArray, double[] yArray) { - return MathX.sumxmy2(xArray, yArray); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Syd.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Syd.java deleted file mode 100644 index 45347f2d51..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Syd.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Syd extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/T.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/T.java deleted file mode 100644 index b322cd985c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/T.java +++ /dev/null @@ -1,55 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; - -public final class T implements Function { - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - switch (args.length) { - default: - return ErrorEval.VALUE_INVALID; - case 1: - break; - } - Eval arg = args[0]; - if (arg instanceof RefEval) { - RefEval re = (RefEval) arg; - arg = re.getInnerValueEval(); - } - - if (arg instanceof StringEval) { - // Text values are returned unmodified - return arg; - } - - if (arg instanceof ErrorEval) { - // Error values also returned unmodified - return arg; - } - // for all other argument types the result is empty string - return StringEval.EMPTY_INSTANCE; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tan.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tan.java deleted file mode 100644 index c8d1e33e5c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tan.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Tan extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = Math.tan(d); - retval = (Double.isNaN(d)) - ? (ValueEval) ErrorEval.VALUE_INVALID - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tanh.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tanh.java deleted file mode 100644 index 1cb0e4fa2c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tanh.java +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 6, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Tanh extends NumericFunction { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - double d = 0; - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - d = ne.getNumberValue(); - } - else if (ve instanceof BlankEval) { - // do nothing - } - else { - retval = ErrorEval.NUM_ERROR; - } - } - - if (retval == null) { - d = MathX.tanh(d); - retval = (Double.isNaN(d) || Double.isInfinite(d)) - ? (ValueEval) ErrorEval.NUM_ERROR - : new NumberEval(d); - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tdist.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tdist.java deleted file mode 100644 index d2a76de2eb..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tdist.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Tdist extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Text.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Text.java deleted file mode 100644 index 833fa82d00..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Text.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Text extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/TextFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/TextFunction.java deleted file mode 100644 index 9da1776127..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/TextFunction.java +++ /dev/null @@ -1,107 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 22, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.AreaEval; -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.StringValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class TextFunction implements Function { - - protected static final String EMPTY_STRING = ""; - - protected ValueEval singleOperandEvaluate(Eval eval, int srcRow, short srcCol) { - ValueEval retval; - if (eval instanceof AreaEval) { - AreaEval ae = (AreaEval) eval; - if (ae.contains(srcRow, srcCol)) { // circular ref! - retval = ErrorEval.CIRCULAR_REF_ERROR; - } - else if (ae.isRow()) { - if (ae.containsColumn(srcCol)) { - ValueEval ve = ae.getValueAt(ae.getFirstRow(), srcCol); - retval = attemptXlateToText(ve); - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else if (ae.isColumn()) { - if (ae.containsRow(srcRow)) { - ValueEval ve = ae.getValueAt(srcRow, ae.getFirstColumn()); - retval = attemptXlateToText(ve); - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else { - retval = attemptXlateToText((ValueEval) eval); - } - return retval; - } - - - /** - * converts from Different ValueEval types to StringEval. - * Note: AreaEvals are not handled, if arg is an AreaEval, - * the returned value is ErrorEval.VALUE_INVALID - * @param ve - */ - protected ValueEval attemptXlateToText(ValueEval ve) { - ValueEval retval; - if (ve instanceof StringValueEval) { - retval = ve; - } - else if (ve instanceof RefEval) { - RefEval re = (RefEval) ve; - ValueEval ive = re.getInnerValueEval(); - if (ive instanceof StringValueEval) { - retval = ive; - } - else if (ive instanceof BlankEval) { - retval = ive; - } - else { - retval = ErrorEval.VALUE_INVALID; - } - } - else if (ve instanceof BlankEval) { - retval = ve; - } - else { - retval = ErrorEval.VALUE_INVALID; - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Textref.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Textref.java deleted file mode 100644 index 8fa2514f68..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Textref.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Textref extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Time.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Time.java deleted file mode 100644 index 2b85da168b..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Time.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Time extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Timevalue.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Timevalue.java deleted file mode 100644 index 049bd30ff0..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Timevalue.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Timevalue extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tinv.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tinv.java deleted file mode 100644 index dab7dcd0e0..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Tinv.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Tinv extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Today.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Today.java deleted file mode 100644 index 6260d20a58..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Today.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Today extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Transpose.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Transpose.java deleted file mode 100644 index cd414ff1c8..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Transpose.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Transpose extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trend.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trend.java deleted file mode 100644 index 80cece928c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trend.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Trend extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trim.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trim.java deleted file mode 100644 index 87e29ee34d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trim.java +++ /dev/null @@ -1,53 +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.Eval; -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.StringEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * An implementation of the TRIM function: - * Removes leading and trailing spaces from value if evaluated operand - * value is string. - * @author Manda Wilson < wilson at c bio dot msk cc dot org > - */ -public final class Trim extends TextFunction { - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - - if(args.length != 1) { - return ErrorEval.VALUE_INVALID; - } - - try { - ValueEval veval = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - - String str = OperandResolver.coerceValueToString(veval); - str = str.trim(); - if(str.length() < 1) { - return StringEval.EMPTY_INSTANCE; - } - return new StringEval(str); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trimmean.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trimmean.java deleted file mode 100644 index 4775a9ee90..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trimmean.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Trimmean extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/True.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/True.java deleted file mode 100644 index 78df7776a1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/True.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. -*/ -/* - * Created on May 6, 2005 - * - */ -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.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class True implements Function { - - public Eval evaluate(Eval[] operands, int srcRow, short srcCol) { - ValueEval retval; - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 0: - retval = BoolEval.TRUE; - } - return retval; - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trunc.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trunc.java deleted file mode 100644 index 65fedd126d..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Trunc.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Trunc extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ttest.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ttest.java deleted file mode 100644 index b453043c13..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ttest.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Ttest extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Type.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Type.java deleted file mode 100644 index 423038211f..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Type.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Type extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Upper.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Upper.java deleted file mode 100644 index 5146a6641c..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Upper.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.StringValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class Upper extends TextFunction { - - - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - String s = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - if (ve instanceof StringValueEval) { - StringValueEval sve = (StringValueEval) ve; - s = sve.getStringValue(); - } - else if (ve instanceof BlankEval) {} - else { - retval = ErrorEval.VALUE_INVALID; - break; - } - } - - if (retval == null) { - s = (s == null) ? EMPTY_STRING : s; - retval = new StringEval(s.toUpperCase()); - } - - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Usdollar.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Usdollar.java deleted file mode 100644 index 3baf71c9b3..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Usdollar.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Usdollar extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Value.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Value.java deleted file mode 100644 index 6772dcf283..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Value.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Value extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Var.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Var.java deleted file mode 100644 index 2b0a3b67c7..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Var.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Var extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vara.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vara.java deleted file mode 100644 index c484c5a9ea..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vara.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Vara extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Varp.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Varp.java deleted file mode 100644 index e8c8bd30dc..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Varp.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Varp extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Varpa.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Varpa.java deleted file mode 100644 index 290b97de89..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Varpa.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Varpa extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vdb.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vdb.java deleted file mode 100644 index 5fb594d6ee..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vdb.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Vdb extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vlookup.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vlookup.java deleted file mode 100644 index 7d27491df1..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Vlookup.java +++ /dev/null @@ -1,123 +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.Eval; -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; -/** - * 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. - * - * Syntax:
    - * VLOOKUP(lookup_value, table_array, col_index_num, range_lookup)

    - * - * lookup_value The value to be found in the first column of the table array.
    - * table_array An area reference for the lookup data.
    - * col_index_num a 1 based index specifying which column value of the lookup data will be returned.
    - * range_lookup If TRUE (default), VLOOKUP finds the largest value less than or equal to - * the lookup_value. If FALSE, only exact matches will be considered
    - * - * @author Josh Micich - */ -public final class Vlookup implements Function { - - private static final class ColumnVector implements ValueVector { - - private final AreaEval _tableArray; - private final int _size; - private final int _columnAbsoluteIndex; - private final int _firstRowAbsoluteIndex; - - public ColumnVector(AreaEval tableArray, int columnIndex) { - _columnAbsoluteIndex = tableArray.getFirstColumn() + columnIndex; - if(!tableArray.containsColumn((short)_columnAbsoluteIndex)) { - int lastColIx = tableArray.getLastColumn() - tableArray.getFirstColumn(); - throw new IllegalArgumentException("Specified column index (" + columnIndex - + ") is outside the allowed range (0.." + lastColIx + ")"); - } - _tableArray = tableArray; - _size = tableArray.getLastRow() - tableArray.getFirstRow() + 1; - if(_size < 1) { - throw new RuntimeException("bad table array size zero"); - } - _firstRowAbsoluteIndex = tableArray.getFirstRow(); - } - - public ValueEval getItem(int index) { - if(index>_size) { - throw new ArrayIndexOutOfBoundsException("Specified index (" + index - + ") is outside the allowed range (0.." + (_size-1) + ")"); - } - return _tableArray.getValueAt(_firstRowAbsoluteIndex + index, (short)_columnAbsoluteIndex); - } - public int getSize() { - return _size; - } - } - - public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - Eval arg3 = null; - switch(args.length) { - case 4: - arg3 = args[3]; // important: assumed array element is never null - case 3: - break; - default: - // wrong number of arguments - return ErrorEval.VALUE_INVALID; - } - try { - // Evaluation order: - // arg0 lookup_value, arg1 table_array, arg3 range_lookup, find lookup value, arg2 col_index, fetch result - ValueEval lookupValue = OperandResolver.getSingleValue(args[0], srcCellRow, srcCellCol); - AreaEval tableArray = LookupUtils.resolveTableArrayArg(args[1]); - boolean isRangeLookup = LookupUtils.resolveRangeLookupArg(arg3, srcCellRow, srcCellCol); - int rowIndex = LookupUtils.lookupIndexOfValue(lookupValue, new ColumnVector(tableArray, 0), isRangeLookup); - ValueEval veColIndex = OperandResolver.getSingleValue(args[2], srcCellRow, srcCellCol); - int colIndex = LookupUtils.resolveRowOrColIndexArg(veColIndex); - ValueVector resultCol = createResultColumnVector(tableArray, colIndex); - return resultCol.getItem(rowIndex); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - } - - - /** - * Returns one column from an AreaEval - * - * @throws EvaluationException (#VALUE!) if colIndex is negative, (#REF!) if colIndex is too high - */ - private ValueVector createResultColumnVector(AreaEval tableArray, int colIndex) throws EvaluationException { - if(colIndex < 0) { - throw EvaluationException.invalidValue(); - } - int nCols = tableArray.getLastColumn() - tableArray.getFirstColumn() + 1; - - if(colIndex >= nCols) { - throw EvaluationException.invalidRef(); - } - return new ColumnVector(tableArray, colIndex); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Volatile.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Volatile.java deleted file mode 100644 index 734eb0fbe7..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Volatile.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Volatile extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Weekday.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Weekday.java deleted file mode 100644 index 7de5f952b3..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Weekday.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Weekday extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Weibull.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Weibull.java deleted file mode 100644 index b2a4895fad..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Weibull.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Weibull extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java deleted file mode 100644 index b989c33a26..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/XYNumericFunction.java +++ /dev/null @@ -1,203 +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.Eval; -import org.apache.poi.hssf.record.formula.eval.EvaluationException; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class XYNumericFunction implements Function { - protected static final int X = 0; - protected static final int Y = 1; - - protected static final class DoubleArrayPair { - - private final double[] _xArray; - private final double[] _yArray; - - public DoubleArrayPair(double[] xArray, double[] yArray) { - _xArray = xArray; - _yArray = yArray; - } - public double[] getXArray() { - return _xArray; - } - public double[] getYArray() { - return _yArray; - } - } - - - public final Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) { - if(args.length != 2) { - return ErrorEval.VALUE_INVALID; - } - - double[][] values; - try { - values = getValues(args[0], args[1]); - } catch (EvaluationException e) { - return e.getErrorEval(); - } - if (values==null - || values[X] == null || values[Y] == null - || values[X].length == 0 || values[Y].length == 0 - || values[X].length != values[Y].length) { - return ErrorEval.VALUE_INVALID; - } - - double d = evaluate(values[X], values[Y]); - if (Double.isNaN(d) || Double.isInfinite(d)) { - return ErrorEval.NUM_ERROR; - } - return new NumberEval(d); - } - protected abstract double evaluate(double[] xArray, double[] yArray); - - /** - * Returns a double array that contains values for the numeric cells - * from among the list of operands. Blanks and Blank equivalent cells - * are ignored. Error operands or cells containing operands of type - * that are considered invalid and would result in #VALUE! error in - * excel cause this function to return null. - */ - private static double[][] getNumberArray(Eval[] xops, Eval[] yops) throws EvaluationException { - - // check for errors first: size mismatch, value errors in x, value errors in y - - int nArrayItems = xops.length; - if(nArrayItems != yops.length) { - throw new EvaluationException(ErrorEval.NA); - } - for (int i = 0; i < xops.length; i++) { - Eval eval = xops[i]; - if (eval instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) eval); - } - } - for (int i = 0; i < yops.length; i++) { - Eval eval = yops[i]; - if (eval instanceof ErrorEval) { - throw new EvaluationException((ErrorEval) eval); - } - } - - double[] xResult = new double[nArrayItems]; - double[] yResult = new double[nArrayItems]; - - int count = 0; - - for (int i=0, iSize=nArrayItems; i len) { - tarr = new double[len]; - System.arraycopy(arr, 0, tarr, 0, len); - } - return tarr; - } - - private static boolean isNumberEval(Eval eval) { - boolean retval = false; - - if (eval instanceof NumberEval) { - retval = true; - } - else if (eval instanceof RefEval) { - RefEval re = (RefEval) eval; - ValueEval ve = re.getInnerValueEval(); - retval = (ve instanceof NumberEval); - } - - return retval; - } - - private static double getDoubleValue(Eval eval) { - double retval = 0; - if (eval instanceof NumberEval) { - NumberEval ne = (NumberEval) eval; - retval = ne.getNumberValue(); - } - else if (eval instanceof RefEval) { - RefEval re = (RefEval) eval; - ValueEval ve = re.getInnerValueEval(); - retval = (ve instanceof NumberEval) - ? ((NumberEval) ve).getNumberValue() - : Double.NaN; - } - else if (eval instanceof ErrorEval) { - retval = Double.NaN; - } - return retval; - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Year.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Year.java deleted file mode 100644 index b461a09668..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Year.java +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import org.apache.poi.hssf.record.formula.eval.BlankEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -import org.apache.poi.hssf.usermodel.HSSFDateUtil; - -/** - * - * @author Guenter Kickinger g.kickinger@gmx.net - * - */ - -public class Year extends NumericFunction { - - /* (non-Javadoc) - * @see org.apache.poi.hssf.record.formula.functions.Function#evaluate(org.apache.poi.hssf.record.formula.eval.Eval[], int, short) - */ - public Eval evaluate(Eval[] operands, int srcCellRow, short srcCellCol) { - ValueEval retval = null; - - switch (operands.length) { - default: - retval = ErrorEval.VALUE_INVALID; - break; - case 1: - ValueEval ve = singleOperandEvaluate(operands[0], srcCellRow, srcCellCol); - if (ve instanceof NumericValueEval) { - NumericValueEval ne = (NumericValueEval) ve; - if (HSSFDateUtil.isValidExcelDate(ne.getNumberValue())) { - java.util.Date d = HSSFDateUtil.getJavaDate(ne.getNumberValue(), false); // XXX fix 1900/1904 problem - retval = new NumberEval(d.getYear()+1900); - } else { - retval = ErrorEval.NUM_ERROR; - } - } - else if (ve instanceof BlankEval) { - // do nothing - } else { - retval = ErrorEval.NUM_ERROR; - } - } - return retval; - } -} \ No newline at end of file diff --git a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ztest.java b/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ztest.java deleted file mode 100644 index ed12b63328..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/record/formula/functions/Ztest.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. -*/ -/* - * Created on May 15, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -public class Ztest extends NotImplementedFunction { - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java b/src/scratchpad/src/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java deleted file mode 100755 index 90f5807ff5..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/usermodel/EvaluationCycleDetector.java +++ /dev/null @@ -1,150 +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.usermodel; - -import java.util.ArrayList; -import java.util.List; - -/** - * Instances of this class keep track of multiple dependent cell evaluations due - * to recursive calls to HSSFFormulaEvaluator.internalEvaluate(). - * The main purpose of this class is to detect an attempt to evaluate a cell - * that is already being evaluated. In other words, it detects circular - * references in spreadsheet formulas. - * - * @author Josh Micich - */ -final class EvaluationCycleDetector { - - /** - * Stores the parameters that identify the evaluation of one cell.
    - */ - private static final class CellEvaluationFrame { - - private final HSSFWorkbook _workbook; - private final HSSFSheet _sheet; - private final int _srcRowNum; - private final int _srcColNum; - - public CellEvaluationFrame(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { - if (workbook == null) { - throw new IllegalArgumentException("workbook must not be null"); - } - if (sheet == null) { - throw new IllegalArgumentException("sheet must not be null"); - } - _workbook = workbook; - _sheet = sheet; - _srcRowNum = srcRowNum; - _srcColNum = srcColNum; - } - - public boolean equals(Object obj) { - CellEvaluationFrame other = (CellEvaluationFrame) obj; - if (_workbook != other._workbook) { - return false; - } - if (_sheet != other._sheet) { - return false; - } - if (_srcRowNum != other._srcRowNum) { - return false; - } - if (_srcColNum != other._srcColNum) { - return false; - } - return true; - } - - /** - * @return human readable string for debug purposes - */ - public String formatAsString() { - return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _workbook.getSheetIndex(_sheet); - } - - public String toString() { - StringBuffer sb = new StringBuffer(64); - sb.append(getClass().getName()).append(" ["); - sb.append(formatAsString()); - sb.append("]"); - return sb.toString(); - } - } - - private final List _evaluationFrames; - - public EvaluationCycleDetector() { - _evaluationFrames = new ArrayList(); - } - - /** - * Notifies this evaluation tracker that evaluation of the specified cell is - * about to start.
    - * - * In the case of a true return code, the caller should - * continue evaluation of the specified cell, and also be sure to call - * endEvaluate() when complete.
    - * - * In the case of a false return code, the caller should - * return an evaluation result of - * ErrorEval.CIRCULAR_REF_ERROR, and not call endEvaluate(). - *
    - * @return true if the specified cell has not been visited yet in the current - * evaluation. false if the specified cell is already being evaluated. - */ - public boolean startEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { - CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum); - if (_evaluationFrames.contains(cef)) { - return false; - } - _evaluationFrames.add(cef); - return true; - } - - /** - * Notifies this evaluation tracker that the evaluation of the specified - * cell is complete.

    - * - * Every successful call to startEvaluate must be followed by a - * call to endEvaluate (recommended in a finally block) to enable - * proper tracking of which cells are being evaluated at any point in time.

    - * - * Assuming a well behaved client, parameters to this method would not be - * required. However, they have been included to assert correct behaviour, - * and form more meaningful error messages. - */ - public void endEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) { - int nFrames = _evaluationFrames.size(); - if (nFrames < 1) { - throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate"); - } - - nFrames--; - CellEvaluationFrame cefExpected = (CellEvaluationFrame) _evaluationFrames.get(nFrames); - CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum); - if (!cefActual.equals(cefExpected)) { - throw new RuntimeException("Wrong cell specified. " - + "Corresponding startEvaluate() call was for cell {" - + cefExpected.formatAsString() + "} this endEvaluate() call is for cell {" - + cefActual.formatAsString() + "}"); - } - // else - no problems so pop current frame - _evaluationFrames.remove(nFrames); - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/usermodel/EvaluationCycleDetectorManager.java b/src/scratchpad/src/org/apache/poi/hssf/usermodel/EvaluationCycleDetectorManager.java deleted file mode 100755 index a06cd201e2..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/usermodel/EvaluationCycleDetectorManager.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.usermodel; - -/** - * This class makes an EvaluationCycleDetector instance available to - * each thread via a ThreadLocal in order to avoid adding a parameter - * to a few protected methods within HSSFFormulaEvaluator. - * - * @author Josh Micich - */ -final class EvaluationCycleDetectorManager { - - ThreadLocal tl = null; - private static ThreadLocal _tlEvaluationTracker = new ThreadLocal() { - protected synchronized Object initialValue() { - return new EvaluationCycleDetector(); - } - }; - - /** - * @return - */ - public static EvaluationCycleDetector getTracker() { - return (EvaluationCycleDetector) _tlEvaluationTracker.get(); - } - - private EvaluationCycleDetectorManager() { - // no instances of this class - } -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java b/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java deleted file mode 100644 index bb16fdfadd..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java +++ /dev/null @@ -1,778 +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.usermodel; - -import java.lang.reflect.Constructor; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Stack; - -import org.apache.poi.hssf.model.FormulaParser; -import org.apache.poi.hssf.model.Workbook; -import org.apache.poi.hssf.record.formula.Area3DPtg; -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.AttrPtg; -import org.apache.poi.hssf.record.formula.BoolPtg; -import org.apache.poi.hssf.record.formula.ControlPtg; -import org.apache.poi.hssf.record.formula.IntPtg; -import org.apache.poi.hssf.record.formula.MemErrPtg; -import org.apache.poi.hssf.record.formula.MissingArgPtg; -import org.apache.poi.hssf.record.formula.NamePtg; -import org.apache.poi.hssf.record.formula.NameXPtg; -import org.apache.poi.hssf.record.formula.NumberPtg; -import org.apache.poi.hssf.record.formula.OperationPtg; -import org.apache.poi.hssf.record.formula.ParenthesisPtg; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.Ref3DPtg; -import org.apache.poi.hssf.record.formula.ReferencePtg; -import org.apache.poi.hssf.record.formula.StringPtg; -import org.apache.poi.hssf.record.formula.UnionPtg; -import org.apache.poi.hssf.record.formula.UnknownPtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -import org.apache.poi.hssf.record.formula.eval.Area3DEval; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.FunctionEval; -import org.apache.poi.hssf.record.formula.eval.NameEval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.OperationEval; -import org.apache.poi.hssf.record.formula.eval.Ref2DEval; -import org.apache.poi.hssf.record.formula.eval.Ref3DEval; -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 > - * - */ -public class HSSFFormulaEvaluator { - - // params to lookup the right constructor using reflection - private static final Class[] VALUE_CONTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class }; - - private static final Class[] AREA3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval[].class }; - - private static final Class[] REFERENCE_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class }; - - private static final Class[] REF3D_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class, ValueEval.class }; - - // Maps for mapping *Eval to *Ptg - private static final Map VALUE_EVALS_MAP = new HashMap(); - - /* - * Following is the mapping between the Ptg tokens returned - * by the FormulaParser and the *Eval classes that are used - * by the FormulaEvaluator - */ - static { - VALUE_EVALS_MAP.put(BoolPtg.class, BoolEval.class); - VALUE_EVALS_MAP.put(IntPtg.class, NumberEval.class); - VALUE_EVALS_MAP.put(NumberPtg.class, NumberEval.class); - VALUE_EVALS_MAP.put(StringPtg.class, StringEval.class); - - } - - - protected HSSFRow row; - protected HSSFSheet sheet; - protected HSSFWorkbook workbook; - - public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) { - this.sheet = sheet; - this.workbook = workbook; - } - - public void setCurrentRow(HSSFRow row) { - this.row = row; - } - - - /** - * Returns an underlying FormulaParser, for the specified - * Formula String and HSSFWorkbook. - * This will allow you to generate the Ptgs yourself, if - * your needs are more complex than just having the - * formula evaluated. - */ - public static FormulaParser getUnderlyingParser(HSSFWorkbook workbook, String formula) { - return new FormulaParser(formula, workbook.getWorkbook()); - } - - /** - * If cell contains a formula, the formula is evaluated and returned, - * else the CellValue simply copies the appropriate cell value from - * the cell and also its cell type. This method should be preferred over - * evaluateInCell() when the call should not modify the contents of the - * original cell. - * @param cell - */ - public CellValue evaluate(HSSFCell cell) { - CellValue retval = null; - if (cell != null) { - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_BLANK: - retval = new CellValue(HSSFCell.CELL_TYPE_BLANK); - break; - case HSSFCell.CELL_TYPE_BOOLEAN: - retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN); - retval.setBooleanValue(cell.getBooleanCellValue()); - break; - case HSSFCell.CELL_TYPE_ERROR: - retval = new CellValue(HSSFCell.CELL_TYPE_ERROR); - retval.setErrorValue(cell.getErrorCellValue()); - break; - case HSSFCell.CELL_TYPE_FORMULA: - retval = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook)); - break; - case HSSFCell.CELL_TYPE_NUMERIC: - retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC); - retval.setNumberValue(cell.getNumericCellValue()); - break; - case HSSFCell.CELL_TYPE_STRING: - retval = new CellValue(HSSFCell.CELL_TYPE_STRING); - retval.setRichTextStringValue(cell.getRichStringCellValue()); - break; - } - } - return retval; - } - - - /** - * If cell contains formula, it evaluates the formula, - * and saves the result of the formula. The cell - * remains as a formula cell. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the type of the formula result is returned, - * so you know what kind of value is also stored with - * the formula. - *

    -     * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
    -     * 
    - * Be aware that your cell will hold both the formula, - * and the result. If you want the cell replaced with - * the result of the formula, use {@link #evaluateInCell(HSSFCell)} - * @param cell The cell to evaluate - * @return The type of the formula result (the cell's type remains as HSSFCell.CELL_TYPE_FORMULA however) - */ - public int evaluateFormulaCell(HSSFCell cell) { - if (cell != null) { - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_FORMULA: - CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook)); - switch (cv.getCellType()) { - case HSSFCell.CELL_TYPE_BOOLEAN: - cell.setCellValue(cv.getBooleanValue()); - break; - case HSSFCell.CELL_TYPE_ERROR: - cell.setCellValue(cv.getErrorValue()); - break; - case HSSFCell.CELL_TYPE_NUMERIC: - cell.setCellValue(cv.getNumberValue()); - break; - case HSSFCell.CELL_TYPE_STRING: - cell.setCellValue(cv.getRichTextStringValue()); - break; - case HSSFCell.CELL_TYPE_BLANK: - break; - case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula - break; - } - return cv.getCellType(); - } - } - return -1; - } - - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the same instance of HSSFCell is returned to - * allow chained calls like: - *
    -     * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
    -     * 
    - * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #evaluateFormulaCell(HSSFCell)} - * @param cell - */ - public HSSFCell evaluateInCell(HSSFCell cell) { - if (cell != null) { - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_FORMULA: - CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook)); - switch (cv.getCellType()) { - case HSSFCell.CELL_TYPE_BOOLEAN: - cell.setCellType(HSSFCell.CELL_TYPE_BOOLEAN); - cell.setCellValue(cv.getBooleanValue()); - break; - case HSSFCell.CELL_TYPE_ERROR: - cell.setCellType(HSSFCell.CELL_TYPE_ERROR); - cell.setCellValue(cv.getErrorValue()); - break; - case HSSFCell.CELL_TYPE_NUMERIC: - cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); - cell.setCellValue(cv.getNumberValue()); - break; - case HSSFCell.CELL_TYPE_STRING: - cell.setCellType(HSSFCell.CELL_TYPE_STRING); - cell.setCellValue(cv.getRichTextStringValue()); - break; - case HSSFCell.CELL_TYPE_BLANK: - break; - case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula - break; - } - } - } - return cell; - } - - /** - * Loops over all cells in all sheets of the supplied - * workbook. - * For cells that contain formulas, their formulas are - * evaluated, and the results are saved. These cells - * remain as formula cells. - * For cells that do not contain formulas, no changes - * are made. - * This is a helpful wrapper around looping over all - * cells, and calling evaluateFormulaCell on each one. - */ - public static void evaluateAllFormulaCells(HSSFWorkbook wb) { - for(int i=0; i= 0; j--) { - Eval p = (Eval) stack.pop(); - ops[j] = p; - } - Eval opresult = invokeOperation(operation, ops, srcRowNum, srcColNum, workbook, sheet); - stack.push(opresult); - } - else if (ptg instanceof ReferencePtg) { - ReferencePtg refPtg = (ReferencePtg) ptg; - int colIx = refPtg.getColumn(); - int rowIx = refPtg.getRow(); - HSSFRow row = sheet.getRow(rowIx); - HSSFCell cell = (row != null) ? row.getCell(colIx) : null; - stack.push(createRef2DEval(refPtg, cell, row, sheet, workbook)); - } - else if (ptg instanceof Ref3DPtg) { - Ref3DPtg refPtg = (Ref3DPtg) ptg; - int colIx = refPtg.getColumn(); - int rowIx = refPtg.getRow(); - Workbook wb = workbook.getWorkbook(); - HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex())); - HSSFRow row = xsheet.getRow(rowIx); - HSSFCell cell = (row != null) ? row.getCell(colIx) : null; - stack.push(createRef3DEval(refPtg, cell, row, xsheet, workbook)); - } - else if (ptg instanceof AreaPtg) { - AreaPtg ap = (AreaPtg) ptg; - AreaEval ae = evaluateAreaPtg(sheet, workbook, ap); - stack.push(ae); - } - else if (ptg instanceof Area3DPtg) { - Area3DPtg a3dp = (Area3DPtg) ptg; - AreaEval ae = evaluateArea3dPtg(workbook, a3dp); - stack.push(ae); - } - else { - Eval ptgEval = getEvalForPtg(ptg); - stack.push(ptgEval); - } - } - - ValueEval value = ((ValueEval) stack.pop()); - if (!stack.isEmpty()) { - throw new IllegalStateException("evaluation stack not empty"); - } - value = dereferenceValue(value, srcRowNum, srcColNum); - if (value instanceof BlankEval) { - // Note Excel behaviour here. A blank final final value is converted to zero. - return NumberEval.ZERO; - // Formulas _never_ evaluate to blank. If a formula appears to have evaluated to - // blank, the actual value is empty string. This can be verified with ISBLANK(). - } - return value; - } - - /** - * Dereferences a single value from any AreaEval or RefEval evaluation result. - * If the supplied evaluationResult is just a plain value, it is returned as-is. - * @return a NumberEval, StringEval, BoolEval, - * BlankEval or ErrorEval. Never null. - */ - private static ValueEval dereferenceValue(ValueEval evaluationResult, int srcRowNum, short srcColNum) { - if (evaluationResult instanceof RefEval) { - RefEval rv = (RefEval) evaluationResult; - return rv.getInnerValueEval(); - } - if (evaluationResult instanceof AreaEval) { - AreaEval ae = (AreaEval) evaluationResult; - if (ae.isRow()) { - if(ae.isColumn()) { - return ae.getValues()[0]; - } - return ae.getValueAt(ae.getFirstRow(), srcColNum); - } - if (ae.isColumn()) { - return ae.getValueAt(srcRowNum, ae.getFirstColumn()); - } - return ErrorEval.VALUE_INVALID; - } - return evaluationResult; - } - - private static Eval invokeOperation(OperationEval operation, Eval[] ops, int srcRowNum, short srcColNum, - HSSFWorkbook workbook, HSSFSheet sheet) { - - if(operation instanceof FunctionEval) { - FunctionEval fe = (FunctionEval) operation; - if(fe.isFreeRefFunction()) { - return fe.getFreeRefFunction().evaluate(ops, srcRowNum, srcColNum, workbook, sheet); - } - } - return operation.evaluate(ops, srcRowNum, srcColNum); - } - - public static AreaEval evaluateAreaPtg(HSSFSheet sheet, HSSFWorkbook workbook, AreaPtg ap) { - int row0 = ap.getFirstRow(); - int col0 = ap.getFirstColumn(); - int row1 = ap.getLastRow(); - int col1 = ap.getLastColumn(); - - // If the last row is -1, then the - // reference is for the rest of the column - // (eg C:C) - // TODO: Handle whole column ranges properly - if(row1 == -1 && row0 >= 0) { - row1 = (short)sheet.getLastRowNum(); - } - ValueEval[] values = evalArea(workbook, sheet, row0, col0, row1, col1); - return new Area2DEval(ap, values); - } - - public static AreaEval evaluateArea3dPtg(HSSFWorkbook workbook, Area3DPtg a3dp) { - int row0 = a3dp.getFirstRow(); - int col0 = a3dp.getFirstColumn(); - int row1 = a3dp.getLastRow(); - int col1 = a3dp.getLastColumn(); - Workbook wb = workbook.getWorkbook(); - HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex())); - - // If the last row is -1, then the - // reference is for the rest of the column - // (eg C:C) - // TODO: Handle whole column ranges properly - if(row1 == -1 && row0 >= 0) { - row1 = (short)xsheet.getLastRowNum(); - } - - ValueEval[] values = evalArea(workbook, xsheet, row0, col0, row1, col1); - return new Area3DEval(a3dp, values); - } - - private static ValueEval[] evalArea(HSSFWorkbook workbook, HSSFSheet sheet, - int row0, int col0, int row1, int col1) { - ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)]; - for (int x = row0; sheet != null && x < row1 + 1; x++) { - HSSFRow row = sheet.getRow(x); - for (int y = col0; y < col1 + 1; y++) { - ValueEval cellEval; - if(row == null) { - cellEval = BlankEval.INSTANCE; - } else { - cellEval = getEvalForCell(row.getCell(y), row, sheet, workbook); - } - values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = cellEval; - } - } - return values; - } - - /** - * returns an appropriate Eval impl instance for the Ptg. The Ptg must be - * one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg, - * StringPtg, BoolPtg
    special Note: OperationPtg subtypes cannot be - * passed here! - * - * @param ptg - */ - protected static Eval getEvalForPtg(Ptg ptg) { - Eval retval = null; - - Class clazz = (Class) VALUE_EVALS_MAP.get(ptg.getClass()); - try { - if (ptg instanceof Area3DPtg) { - Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY); - retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); - } - else if (ptg instanceof AreaPtg) { - Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY); - retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); - } - else if (ptg instanceof ReferencePtg) { - Constructor constructor = clazz.getConstructor(REFERENCE_CONSTRUCTOR_CLASS_ARRAY); - retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); - } - else if (ptg instanceof Ref3DPtg) { - Constructor constructor = clazz.getConstructor(REF3D_CONSTRUCTOR_CLASS_ARRAY); - retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg }); - } - else { - if (ptg instanceof IntPtg || ptg instanceof NumberPtg || ptg instanceof StringPtg - || ptg instanceof BoolPtg) { - Constructor constructor = clazz.getConstructor(VALUE_CONTRUCTOR_CLASS_ARRAY); - retval = (ValueEval) constructor.newInstance(new Ptg[] { ptg }); - } - } - } - catch (Exception e) { - throw new RuntimeException("Fatal Error: ", e); - } - return retval; - - } - - /** - * Given a cell, find its type and from that create an appropriate ValueEval - * impl instance and return that. Since the cell could be an external - * reference, we need the sheet that this belongs to. - * Non existent cells are treated as empty. - * @param cell - * @param sheet - * @param workbook - */ - protected static ValueEval getEvalForCell(HSSFCell cell, HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) { - - if (cell == null) { - return BlankEval.INSTANCE; - } - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_NUMERIC: - return new NumberEval(cell.getNumericCellValue()); - case HSSFCell.CELL_TYPE_STRING: - return new StringEval(cell.getRichStringCellValue().getString()); - case HSSFCell.CELL_TYPE_FORMULA: - return internalEvaluate(cell, row, sheet, workbook); - case HSSFCell.CELL_TYPE_BOOLEAN: - return BoolEval.valueOf(cell.getBooleanCellValue()); - case HSSFCell.CELL_TYPE_BLANK: - return BlankEval.INSTANCE; - case HSSFCell.CELL_TYPE_ERROR: - return ErrorEval.valueOf(cell.getErrorCellValue()); - } - throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")"); - } - - /** - * Creates a Ref2DEval for ReferencePtg. - * Non existent cells are treated as RefEvals containing BlankEval. - */ - private static Ref2DEval createRef2DEval(ReferencePtg ptg, HSSFCell cell, - HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) { - if (cell == null) { - return new Ref2DEval(ptg, BlankEval.INSTANCE); - } - - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_NUMERIC: - return new Ref2DEval(ptg, new NumberEval(cell.getNumericCellValue())); - case HSSFCell.CELL_TYPE_STRING: - return new Ref2DEval(ptg, new StringEval(cell.getRichStringCellValue().getString())); - case HSSFCell.CELL_TYPE_FORMULA: - return new Ref2DEval(ptg, internalEvaluate(cell, row, sheet, workbook)); - case HSSFCell.CELL_TYPE_BOOLEAN: - return new Ref2DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue())); - case HSSFCell.CELL_TYPE_BLANK: - return new Ref2DEval(ptg, BlankEval.INSTANCE); - case HSSFCell.CELL_TYPE_ERROR: - return new Ref2DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue())); - } - throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")"); - } - - /** - * create a Ref3DEval for Ref3DPtg. - */ - private static Ref3DEval createRef3DEval(Ref3DPtg ptg, HSSFCell cell, - HSSFRow row, HSSFSheet sheet, HSSFWorkbook workbook) { - if (cell == null) { - return new Ref3DEval(ptg, BlankEval.INSTANCE); - } - switch (cell.getCellType()) { - case HSSFCell.CELL_TYPE_NUMERIC: - return new Ref3DEval(ptg, new NumberEval(cell.getNumericCellValue())); - case HSSFCell.CELL_TYPE_STRING: - return new Ref3DEval(ptg, new StringEval(cell.getRichStringCellValue().getString())); - case HSSFCell.CELL_TYPE_FORMULA: - return new Ref3DEval(ptg, internalEvaluate(cell, row, sheet, workbook)); - case HSSFCell.CELL_TYPE_BOOLEAN: - return new Ref3DEval(ptg, BoolEval.valueOf(cell.getBooleanCellValue())); - case HSSFCell.CELL_TYPE_BLANK: - return new Ref3DEval(ptg, BlankEval.INSTANCE); - case HSSFCell.CELL_TYPE_ERROR: - return new Ref3DEval(ptg, ErrorEval.valueOf(cell.getErrorCellValue())); - } - throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")"); - } - - /** - * Mimics the 'data view' of a cell. This allows formula evaluator - * to return a CellValue instead of precasting the value to String - * or Number or boolean type. - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ - public static final class CellValue { - private int cellType; - private HSSFRichTextString richTextStringValue; - private double numberValue; - private boolean booleanValue; - private byte errorValue; - - /** - * CellType should be one of the types defined in HSSFCell - * @param cellType - */ - public CellValue(int cellType) { - super(); - this.cellType = cellType; - } - /** - * @return Returns the booleanValue. - */ - public boolean getBooleanValue() { - return booleanValue; - } - /** - * @param booleanValue The booleanValue to set. - */ - public void setBooleanValue(boolean booleanValue) { - this.booleanValue = booleanValue; - } - /** - * @return Returns the numberValue. - */ - public double getNumberValue() { - return numberValue; - } - /** - * @param numberValue The numberValue to set. - */ - public void setNumberValue(double numberValue) { - this.numberValue = numberValue; - } - /** - * @return Returns the stringValue. This method is deprecated, use - * getRichTextStringValue instead - * @deprecated - */ - public String getStringValue() { - return richTextStringValue.getString(); - } - /** - * @param stringValue The stringValue to set. This method is deprecated, use - * getRichTextStringValue instead. - * @deprecated - */ - public void setStringValue(String stringValue) { - this.richTextStringValue = new HSSFRichTextString(stringValue); - } - /** - * @return Returns the cellType. - */ - public int getCellType() { - return cellType; - } - /** - * @return Returns the errorValue. - */ - public byte getErrorValue() { - return errorValue; - } - /** - * @param errorValue The errorValue to set. - */ - public void setErrorValue(byte errorValue) { - this.errorValue = errorValue; - } - /** - * @return Returns the richTextStringValue. - */ - public HSSFRichTextString getRichTextStringValue() { - return richTextStringValue; - } - /** - * @param richTextStringValue The richTextStringValue to set. - */ - public void setRichTextStringValue(HSSFRichTextString richTextStringValue) { - this.richTextStringValue = richTextStringValue; - } - } - - /** - * debug method - * - * @param formula - * @param sheet - * @param workbook - */ - void inspectPtgs(String formula) { - FormulaParser fp = new FormulaParser(formula, workbook.getWorkbook()); - fp.parse(); - Ptg[] ptgs = fp.getRPNPtg(); - System.out.println(""); - for (int i = 0, iSize = ptgs.length; i < iSize; i++) { - System.out.println(""); - System.out.println(ptgs[i]); - if (ptgs[i] instanceof OperationPtg) { - System.out.println("numoperands: " + ((OperationPtg) ptgs[i]).getNumberOfOperands()); - } - System.out.println(""); - } - System.out.println(""); - } - -} diff --git a/src/scratchpad/src/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java b/src/scratchpad/src/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java deleted file mode 100755 index 1292009699..0000000000 --- a/src/scratchpad/src/org/apache/poi/hssf/usermodel/OperationEvaluatorFactory.java +++ /dev/null @@ -1,165 +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.usermodel; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -import org.apache.poi.hssf.record.formula.AddPtg; -import org.apache.poi.hssf.record.formula.ConcatPtg; -import org.apache.poi.hssf.record.formula.DividePtg; -import org.apache.poi.hssf.record.formula.EqualPtg; -import org.apache.poi.hssf.record.formula.ExpPtg; -import org.apache.poi.hssf.record.formula.FuncPtg; -import org.apache.poi.hssf.record.formula.FuncVarPtg; -import org.apache.poi.hssf.record.formula.GreaterEqualPtg; -import org.apache.poi.hssf.record.formula.GreaterThanPtg; -import org.apache.poi.hssf.record.formula.LessEqualPtg; -import org.apache.poi.hssf.record.formula.LessThanPtg; -import org.apache.poi.hssf.record.formula.MultiplyPtg; -import org.apache.poi.hssf.record.formula.NotEqualPtg; -import org.apache.poi.hssf.record.formula.OperationPtg; -import org.apache.poi.hssf.record.formula.PercentPtg; -import org.apache.poi.hssf.record.formula.PowerPtg; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.record.formula.SubtractPtg; -import org.apache.poi.hssf.record.formula.UnaryMinusPtg; -import org.apache.poi.hssf.record.formula.UnaryPlusPtg; -import org.apache.poi.hssf.record.formula.eval.AddEval; -import org.apache.poi.hssf.record.formula.eval.ConcatEval; -import org.apache.poi.hssf.record.formula.eval.DivideEval; -import org.apache.poi.hssf.record.formula.eval.EqualEval; -import org.apache.poi.hssf.record.formula.eval.FuncVarEval; -import org.apache.poi.hssf.record.formula.eval.GreaterEqualEval; -import org.apache.poi.hssf.record.formula.eval.GreaterThanEval; -import org.apache.poi.hssf.record.formula.eval.LessEqualEval; -import org.apache.poi.hssf.record.formula.eval.LessThanEval; -import org.apache.poi.hssf.record.formula.eval.MultiplyEval; -import org.apache.poi.hssf.record.formula.eval.NotEqualEval; -import org.apache.poi.hssf.record.formula.eval.OperationEval; -import org.apache.poi.hssf.record.formula.eval.PercentEval; -import org.apache.poi.hssf.record.formula.eval.PowerEval; -import org.apache.poi.hssf.record.formula.eval.SubtractEval; -import org.apache.poi.hssf.record.formula.eval.UnaryMinusEval; -import org.apache.poi.hssf.record.formula.eval.UnaryPlusEval; - -/** - * This class creates OperationEval instances to help evaluate OperationPtg - * formula tokens. - * - * @author Josh Micich - */ -final class OperationEvaluatorFactory { - private static final Class[] OPERATION_CONSTRUCTOR_CLASS_ARRAY = new Class[] { Ptg.class }; - - private static final Map _constructorsByPtgClass = initialiseConstructorsMap(); - - private OperationEvaluatorFactory() { - // no instances of this class - } - - private static Map initialiseConstructorsMap() { - Map m = new HashMap(32); - add(m, AddPtg.class, AddEval.class); - add(m, ConcatPtg.class, ConcatEval.class); - add(m, DividePtg.class, DivideEval.class); - add(m, EqualPtg.class, EqualEval.class); - add(m, FuncPtg.class, FuncVarEval.class); - add(m, FuncVarPtg.class, FuncVarEval.class); - add(m, GreaterEqualPtg.class, GreaterEqualEval.class); - add(m, GreaterThanPtg.class, GreaterThanEval.class); - add(m, LessEqualPtg.class, LessEqualEval.class); - add(m, LessThanPtg.class, LessThanEval.class); - add(m, MultiplyPtg.class, MultiplyEval.class); - add(m, NotEqualPtg.class, NotEqualEval.class); - add(m, PercentPtg.class, PercentEval.class); - add(m, PowerPtg.class, PowerEval.class); - add(m, SubtractPtg.class, SubtractEval.class); - add(m, UnaryMinusPtg.class, UnaryMinusEval.class); - add(m, UnaryPlusPtg.class, UnaryPlusEval.class); - return m; - } - - private static void add(Map m, Class ptgClass, Class evalClass) { - - // perform some validation now, to keep later exception handlers simple - if(!Ptg.class.isAssignableFrom(ptgClass)) { - throw new IllegalArgumentException("Expected Ptg subclass"); - } - if(!OperationEval.class.isAssignableFrom(evalClass)) { - throw new IllegalArgumentException("Expected OperationEval subclass"); - } - if (!Modifier.isPublic(evalClass.getModifiers())) { - throw new RuntimeException("Eval class must be public"); - } - if (Modifier.isAbstract(evalClass.getModifiers())) { - throw new RuntimeException("Eval class must not be abstract"); - } - - Constructor constructor; - try { - constructor = evalClass.getDeclaredConstructor(OPERATION_CONSTRUCTOR_CLASS_ARRAY); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Missing constructor"); - } - if (!Modifier.isPublic(constructor.getModifiers())) { - throw new RuntimeException("Eval constructor must be public"); - } - m.put(ptgClass, constructor); - } - - /** - * returns the OperationEval concrete impl instance corresponding - * to the supplied operationPtg - */ - public static OperationEval create(OperationPtg ptg) { - if(ptg == null) { - throw new IllegalArgumentException("ptg must not be null"); - } - - Class ptgClass = ptg.getClass(); - - Constructor constructor = (Constructor) _constructorsByPtgClass.get(ptgClass); - if(constructor == null) { - if(ptgClass == ExpPtg.class) { - // ExpPtg is used for array formulas and shared formulas. - // it is currently unsupported, and may not even get implemented here - throw new RuntimeException("ExpPtg currently not supported"); - } - throw new RuntimeException("Unexpected operation ptg class (" + ptgClass.getName() + ")"); - } - - Object result; - Object[] initargs = { ptg }; - try { - result = constructor.newInstance(initargs); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - return (OperationEval) result; - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java b/src/scratchpad/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java deleted file mode 100644 index a038a964ee..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java +++ /dev/null @@ -1,360 +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.eventusermodel; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; -import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; -import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RowRecord; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -/** - * Tests for MissingRecordAwareHSSFListener - */ -public final class TestMissingRecordAwareHSSFListener extends TestCase { - - private Record[] r; - - public void setUp() { - String dirname = System.getProperty("HSSF.testdata.path"); - File f = new File(dirname + "/MissingBits.xls"); - - HSSFRequest req = new HSSFRequest(); - MockHSSFListener mockListen = new MockHSSFListener(); - MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(mockListen); - req.addListenerForAllRecords(listener); - - HSSFEventFactory factory = new HSSFEventFactory(); - try { - POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(f)); - factory.processWorkbookEvents(req, fs); - } catch (IOException e) { - throw new RuntimeException(e); - } - r = mockListen.getRecords(); - } - - public void testMissingRowRecords() throws Exception { - - // We have rows 0, 1, 2, 20 and 21 - int row0 = -1; - for(int i=0; i -1); - - // Following row 0, we should have 1, 2, then dummy, then 20+21+22 - assertTrue(r[row0] instanceof RowRecord); - assertTrue(r[row0+1] instanceof RowRecord); - assertTrue(r[row0+2] instanceof RowRecord); - assertTrue(r[row0+3] instanceof MissingRowDummyRecord); - assertTrue(r[row0+4] instanceof MissingRowDummyRecord); - assertTrue(r[row0+5] instanceof MissingRowDummyRecord); - assertTrue(r[row0+6] instanceof MissingRowDummyRecord); - // ... - assertTrue(r[row0+18] instanceof MissingRowDummyRecord); - assertTrue(r[row0+19] instanceof MissingRowDummyRecord); - assertTrue(r[row0+20] instanceof RowRecord); - assertTrue(r[row0+21] instanceof RowRecord); - assertTrue(r[row0+22] instanceof RowRecord); - - // Check things had the right row numbers - RowRecord rr; - rr = (RowRecord)r[row0+2]; - assertEquals(2, rr.getRowNumber()); - rr = (RowRecord)r[row0+20]; - assertEquals(20, rr.getRowNumber()); - rr = (RowRecord)r[row0+21]; - assertEquals(21, rr.getRowNumber()); - - MissingRowDummyRecord mr; - mr = (MissingRowDummyRecord)r[row0+3]; - assertEquals(3, mr.getRowNumber()); - mr = (MissingRowDummyRecord)r[row0+4]; - assertEquals(4, mr.getRowNumber()); - mr = (MissingRowDummyRecord)r[row0+5]; - assertEquals(5, mr.getRowNumber()); - mr = (MissingRowDummyRecord)r[row0+18]; - assertEquals(18, mr.getRowNumber()); - mr = (MissingRowDummyRecord)r[row0+19]; - assertEquals(19, mr.getRowNumber()); - } - - public void testEndOfRowRecords() throws Exception { - - // Find the cell at 0,0 - int cell00 = -1; - for(int i=0; i -1); - - // We have rows 0, 1, 2, 20 and 21 - // Row 0 has 1 entry - // Row 1 has 4 entries - // Row 2 has 6 entries - // Row 20 has 5 entries - // Row 21 has 7 entries - // Row 22 has 12 entries - - // Row 0 - assertFalse(r[cell00+0] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+1] instanceof LastCellOfRowDummyRecord); - // Row 1 - assertFalse(r[cell00+2] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+3] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+4] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+5] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+6] instanceof LastCellOfRowDummyRecord); - // Row 2 - assertFalse(r[cell00+7] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+8] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+9] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+10] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+11] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+12] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+13] instanceof LastCellOfRowDummyRecord); - // Row 3 -> 19 - assertTrue(r[cell00+14] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+15] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+16] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+17] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+18] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+19] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+20] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+21] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+22] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+23] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+24] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+25] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+26] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+27] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+28] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+29] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+30] instanceof LastCellOfRowDummyRecord); - // Row 20 - assertFalse(r[cell00+31] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+32] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+33] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+34] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+35] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+36] instanceof LastCellOfRowDummyRecord); - // Row 21 - assertFalse(r[cell00+37] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+38] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+39] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+40] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+41] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+42] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+43] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+44] instanceof LastCellOfRowDummyRecord); - // Row 22 - assertFalse(r[cell00+45] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+46] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+47] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+48] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+49] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+50] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+51] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+52] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+53] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+54] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+55] instanceof LastCellOfRowDummyRecord); - assertFalse(r[cell00+56] instanceof LastCellOfRowDummyRecord); - assertTrue(r[cell00+57] instanceof LastCellOfRowDummyRecord); - - // Check the numbers of the last seen columns - LastCellOfRowDummyRecord[] lrs = new LastCellOfRowDummyRecord[23]; - int lrscount = 0; - for(int i=0; i -1); - - // We have rows 0, 1, 2, 20 and 21 - // Row 0 has 1 entry, 0 - // Row 1 has 4 entries, 0+3 - // Row 2 has 6 entries, 0+5 - // Row 20 has 5 entries, 0-5 - // Row 21 has 7 entries, 0+1+3+5+6 - // Row 22 has 12 entries, 0+3+4+11 - - // Row 0 - assertFalse(r[cell00+0] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+1] instanceof MissingCellDummyRecord); - - // Row 1 - assertFalse(r[cell00+2] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+3] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+4] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+5] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+6] instanceof MissingCellDummyRecord); - - // Row 2 - assertFalse(r[cell00+7] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+8] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+9] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+10] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+11] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+12] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+13] instanceof MissingCellDummyRecord); - - // Row 3-19 - assertFalse(r[cell00+14] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+15] instanceof MissingCellDummyRecord); - - // Row 20 - assertFalse(r[cell00+31] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+32] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+33] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+34] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+35] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+36] instanceof MissingCellDummyRecord); - - // Row 21 - assertFalse(r[cell00+37] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+38] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+39] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+40] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+41] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+42] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+43] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+44] instanceof MissingCellDummyRecord); - - // Row 22 - assertFalse(r[cell00+45] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+46] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+47] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+48] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+49] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+50] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+51] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+52] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+53] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+54] instanceof MissingCellDummyRecord); - assertTrue(r[cell00+55] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+56] instanceof MissingCellDummyRecord); - assertFalse(r[cell00+57] instanceof MissingCellDummyRecord); - - // Check some numbers - MissingCellDummyRecord mc; - - mc = (MissingCellDummyRecord)r[cell00+3]; - assertEquals(1, mc.getRow()); - assertEquals(1, mc.getColumn()); - mc = (MissingCellDummyRecord)r[cell00+4]; - assertEquals(1, mc.getRow()); - assertEquals(2, mc.getColumn()); - - mc = (MissingCellDummyRecord)r[cell00+8]; - assertEquals(2, mc.getRow()); - assertEquals(1, mc.getColumn()); - mc = (MissingCellDummyRecord)r[cell00+9]; - assertEquals(2, mc.getRow()); - assertEquals(2, mc.getColumn()); - - mc = (MissingCellDummyRecord)r[cell00+55]; - assertEquals(22, mc.getRow()); - assertEquals(10, mc.getColumn()); - } - - private static final class MockHSSFListener implements HSSFListener { - public MockHSSFListener() {} - private final List _records = new ArrayList(); - - public void processRecord(Record record) { - _records.add(record); - - if(record instanceof MissingRowDummyRecord) { - MissingRowDummyRecord mr = (MissingRowDummyRecord)record; - log("Got dummy row " + mr.getRowNumber()); - } - if(record instanceof MissingCellDummyRecord) { - MissingCellDummyRecord mc = (MissingCellDummyRecord)record; - log("Got dummy cell " + mc.getRow() + " " + mc.getColumn()); - } - if(record instanceof LastCellOfRowDummyRecord) { - LastCellOfRowDummyRecord lc = (LastCellOfRowDummyRecord)record; - log("Got end-of row, row was " + lc.getRow() + ", last column was " + lc.getLastColumnNumber()); - } - } - private static void log(String msg) { - if(false) { // successful tests should be quiet - System.out.println(msg); - } - } - public Record[] getRecords() { - Record[] result = new Record[_records.size()]; - _records.toArray(result); - return result; - } - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/model/TestFormulaParserSP.java b/src/scratchpad/testcases/org/apache/poi/hssf/model/TestFormulaParserSP.java deleted file mode 100644 index 0141e1b2a4..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/model/TestFormulaParserSP.java +++ /dev/null @@ -1,110 +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.model; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.model.FormulaParser.FormulaParseException; -import org.apache.poi.hssf.record.formula.FuncVarPtg; -import org.apache.poi.hssf.record.formula.NamePtg; -import org.apache.poi.hssf.record.formula.Ptg; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFName; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; - -/** - * Test the low level formula parser functionality, - * but using parts which need to use the - * HSSFFormulaEvaluator, which is in scratchpad - */ -public final class TestFormulaParserSP extends TestCase { - - public void testWithNamedRange() throws Exception { - HSSFWorkbook workbook = new HSSFWorkbook(); - FormulaParser fp; - Ptg[] ptgs; - - HSSFSheet s = workbook.createSheet("Foo"); - s.createRow(0).createCell((short)0).setCellValue(1.1); - s.createRow(1).createCell((short)0).setCellValue(2.3); - s.createRow(2).createCell((short)2).setCellValue(3.1); - - HSSFName name = workbook.createName(); - name.setNameName("testName"); - name.setReference("A1:A2"); - - fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); - fp.parse(); - ptgs = fp.getRPNPtg(); - assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); - assertEquals(NamePtg.class, ptgs[0].getClass()); - assertEquals(FuncVarPtg.class, ptgs[1].getClass()); - - // Now make it a single cell - name.setReference("C3"); - - fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); - fp.parse(); - ptgs = fp.getRPNPtg(); - assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); - assertEquals(NamePtg.class, ptgs[0].getClass()); - assertEquals(FuncVarPtg.class, ptgs[1].getClass()); - - // And make it non-contiguous - name.setReference("A1:A2,C3"); - fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); - fp.parse(); - ptgs = fp.getRPNPtg(); - assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); - assertEquals(NamePtg.class, ptgs[0].getClass()); - assertEquals(FuncVarPtg.class, ptgs[1].getClass()); - } - - public void testEvaluateFormulaWithRowBeyond32768_Bug44539() { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet(); - wb.setSheetName(0, "Sheet1"); - - HSSFRow row = sheet.createRow(0); - HSSFCell cell = row.createCell((short)0); - cell.setCellFormula("SUM(A32769:A32770)"); - - // put some values in the cells to make the evaluation more interesting - sheet.createRow(32768).createCell((short)0).setCellValue(31); - sheet.createRow(32769).createCell((short)0).setCellValue(11); - - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); - fe.setCurrentRow(row); - CellValue result; - try { - result = fe.evaluate(cell); - } catch (FormulaParseException e) { - if(e.getMessage().equals("Found reference to named range \"A\", but that named range wasn't defined!")) { - fail("Identifed bug 44539"); - } - throw new RuntimeException(e); - } - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, result.getCellType()); - assertEquals(42.0, result.getNumberValue(), 0.0); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java deleted file mode 100755 index 5098c789a7..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.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; - -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Collects all tests the package org.apache.poi.hssf.record.formula.eval. - * - * @author Josh Micich - */ -public class AllFormulaEvalTests { - - public static Test suite() { - TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.eval"); - result.addTestSuite(TestCircularReferences.class); - result.addTestSuite(TestExternalFunction.class); - result.addTestSuite(TestFormulaBugs.class); - result.addTestSuite(TestFormulasFromSpreadsheet.class); - result.addTestSuite(TestPercentEval.class); - result.addTestSuite(TestUnaryPlusEval.class); - return result; - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java deleted file mode 100755 index 72db658f77..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java +++ /dev/null @@ -1,125 +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 junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; -/** - * Tests HSSFFormulaEvaluator for its handling of cell formula circular references. - * - * @author Josh Micich - */ -public final class TestCircularReferences extends TestCase { - /** - * Translates StackOverflowError into AssertionFailedError - */ - private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFSheet sheet, HSSFRow row, HSSFCell testCell) - throws AssertionFailedError { - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); - evaluator.setCurrentRow(row); - try { - return evaluator.evaluate(testCell); - } catch (StackOverflowError e) { - throw new AssertionFailedError( "circular reference caused stack overflow error"); - } - } - /** - * Makes sure that the specified evaluated cell value represents a circular reference error. - */ - private static void confirmCycleErrorCode(CellValue cellValue) { - assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_ERROR); - assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cellValue.getErrorValue()); - } - - - /** - * ASF Bugzilla Bug 44413 - * "INDEX() formula cannot contain its own location in the data array range" - */ - public void testIndexFormula() { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("Sheet1"); - - short colB = 1; - sheet.createRow(0).createCell(colB).setCellValue(1); - sheet.createRow(1).createCell(colB).setCellValue(2); - sheet.createRow(2).createCell(colB).setCellValue(3); - HSSFRow row4 = sheet.createRow(3); - HSSFCell testCell = row4.createCell((short)0); - // This formula should evaluate to the contents of B2, - testCell.setCellFormula("INDEX(A1:B4,2,2)"); - // However the range A1:B4 also includes the current cell A4. If the other parameters - // were 4 and 1, this would represent a circular reference. Since POI 'fully' evaluates - // arguments before invoking operators, POI must handle such potential cycles gracefully. - - - CellValue cellValue = evaluateWithCycles(wb, sheet, row4, testCell); - - assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_NUMERIC); - assertEquals(2, cellValue.getNumberValue(), 0); - } - - /** - * Cell A1 has formula "=A1" - */ - public void testSimpleCircularReference() { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("Sheet1"); - - HSSFRow row = sheet.createRow(0); - HSSFCell testCell = row.createCell((short)0); - testCell.setCellFormula("A1"); - - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); - evaluator.setCurrentRow(row); - CellValue cellValue = evaluateWithCycles(wb, sheet, row, testCell); - - confirmCycleErrorCode(cellValue); - } - - /** - * A1=B1, B1=C1, C1=D1, D1=A1 - */ - public void testMultiLevelCircularReference() { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("Sheet1"); - - HSSFRow row = sheet.createRow(0); - row.createCell((short)0).setCellFormula("B1"); - row.createCell((short)1).setCellFormula("C1"); - row.createCell((short)2).setCellFormula("D1"); - HSSFCell testCell = row.createCell((short)3); - testCell.setCellFormula("A1"); - - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); - evaluator.setCurrentRow(row); - CellValue cellValue = evaluateWithCycles(wb, sheet, row, testCell); - - confirmCycleErrorCode(cellValue); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java deleted file mode 100755 index 27e3338652..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java +++ /dev/null @@ -1,61 +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 junit.framework.TestCase; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFName; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; -/** - * - * @author Josh Micich - */ -public final class TestExternalFunction extends TestCase { - - /** - * Checks that an external function can get invoked from the formula evaluator. - */ - public void testInvoke() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet(); - wb.setSheetName(0, "Sheet1"); - HSSFRow row = sheet.createRow(0); - HSSFCell cell = row.createCell((short)0); - - HSSFName hssfName = wb.createName(); - hssfName.setNameName("myFunc"); - - cell.setCellFormula("myFunc()"); - String actualFormula=cell.getCellFormula(); - assertEquals("myFunc()", actualFormula); - - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); - fe.setCurrentRow(row); - CellValue evalResult = fe.evaluate(cell); - - // Check the return value from ExternalFunction.evaluate() - // TODO - make this test assert something more interesting as soon as ExternalFunction works a bit better - assertEquals(HSSFCell.CELL_TYPE_ERROR, evalResult.getCellType()); - assertEquals(ErrorEval.FUNCTION_NOT_IMPLEMENTED.getErrorCode(), evalResult.getErrorValue()); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java deleted file mode 100755 index 617f5d0d4e..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java +++ /dev/null @@ -1,217 +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.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; - -/** - * Miscellaneous tests for bugzilla entries.

    The test name contains the - * bugzilla bug id. - * - * - * @author Josh Micich - */ -public final class TestFormulaBugs extends TestCase { - - private static final String TEST_DATA_DIR_SYS_PROPERTY_NAME = "HSSF.testdata.path"; - - /** - * Opens a sample file from the standard HSSF test data directory - * - * @return an open InputStream for the specified sample file - */ - private static InputStream openSampleFileStream(String sampleFileName) { - // TODO - move this method somewhere common - String dataDirName = System - .getProperty(TEST_DATA_DIR_SYS_PROPERTY_NAME); - if (dataDirName == null) { - throw new RuntimeException("Must set system property '" - + TEST_DATA_DIR_SYS_PROPERTY_NAME - + "' before running tests"); - } - File dataDir = new File(dataDirName); - if (!dataDir.exists()) { - throw new RuntimeException("Data dir '" + dataDirName - + "' specified by system property '" - + TEST_DATA_DIR_SYS_PROPERTY_NAME + "' does not exist"); - } - File f = new File(dataDir, sampleFileName); - if (!f.exists()) { - throw new RuntimeException("Sample file '" + sampleFileName - + "' not found in data dir '" + dataDirName + "'"); - } - InputStream is; - try { - is = new FileInputStream(f); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - return is; - } - - /** - * Bug 27349 - VLOOKUP with reference to another sheet.

    This test was - * added long after the relevant functionality was fixed. - */ - public void test27349() { - // 27349-vlookupAcrossSheets.xls is bugzilla/attachment.cgi?id=10622 - InputStream is = openSampleFileStream("27349-vlookupAcrossSheets.xls"); - HSSFWorkbook wb; - try { - // original bug may have thrown exception here, or output warning to - // stderr - wb = new HSSFWorkbook(is); - } catch (IOException e) { - throw new RuntimeException(e); - } - - HSSFSheet sheet = wb.getSheetAt(0); - HSSFRow row = sheet.getRow(1); - HSSFCell cell = row.getCell(0); - - // this definitely would have failed due to 27349 - assertEquals("VLOOKUP(1,'DATA TABLE'!$A$8:'DATA TABLE'!$B$10,2)", cell - .getCellFormula()); - - // We might as well evaluate the formula - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); - fe.setCurrentRow(row); - CellValue cv = fe.evaluate(cell); - - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); - assertEquals(3.0, cv.getNumberValue(), 0.0); - } - - /** - * Bug 27405 - isnumber() formula always evaluates to false in if statement

    - * - * seems to be a duplicate of 24925 - */ - public void test27405() { - - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("input"); - // input row 0 - HSSFRow row = sheet.createRow((short) 0); - HSSFCell cell = row.createCell((short) 0); - cell = row.createCell((short) 1); - cell.setCellValue(1); // B1 - // input row 1 - row = sheet.createRow((short) 1); - cell = row.createCell((short) 1); - cell.setCellValue(999); // B2 - - int rno = 4; - row = sheet.createRow(rno); - cell = row.createCell((short) 1); // B5 - cell.setCellFormula("isnumber(b1)"); - cell = row.createCell((short) 3); // D5 - cell.setCellFormula("IF(ISNUMBER(b1),b1,b2)"); - - if (false) { // set true to check excel file manually - // bug report mentions 'Editing the formula in excel "fixes" the problem.' - try { - FileOutputStream fileOut = new FileOutputStream("27405output.xls"); - wb.write(fileOut); - fileOut.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - // use POI's evaluator as an extra sanity check - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); - fe.setCurrentRow(row); - CellValue cv; - cv = fe.evaluate(cell); - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); - assertEquals(1.0, cv.getNumberValue(), 0.0); - - cv = fe.evaluate(row.getCell(1)); - assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, cv.getCellType()); - assertEquals(true, cv.getBooleanValue()); - } - - /** - * Bug 42448 - Can't parse SUMPRODUCT(A!C7:A!C67, B8:B68) / B69

    - */ - public void test42448() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet1 = wb.createSheet("Sheet1"); - - HSSFRow row = sheet1.createRow(0); - HSSFCell cell = row.createCell((short) 0); - - // it's important to create the referenced sheet first - HSSFSheet sheet2 = wb.createSheet("A"); // note name 'A' - // TODO - POI crashes if the formula is added before this sheet - // RuntimeException("Zero length string is an invalid sheet name") - // Excel doesn't crash but the formula doesn't work until it is - // re-entered - - String inputFormula = "SUMPRODUCT(A!C7:A!C67, B8:B68) / B69"; // as per bug report - try { - cell.setCellFormula(inputFormula); - } catch (StringIndexOutOfBoundsException e) { - throw new AssertionFailedError("Identified bug 42448"); - } - - assertEquals("SUMPRODUCT(A!C7:C67,B8:B68)/B69", cell.getCellFormula()); - - // might as well evaluate the sucker... - - addCell(sheet2, 5, 2, 3.0); // A!C6 - addCell(sheet2, 6, 2, 4.0); // A!C7 - addCell(sheet2, 66, 2, 5.0); // A!C67 - addCell(sheet2, 67, 2, 6.0); // A!C68 - - addCell(sheet1, 6, 1, 7.0); // B7 - addCell(sheet1, 7, 1, 8.0); // B8 - addCell(sheet1, 67, 1, 9.0); // B68 - addCell(sheet1, 68, 1, 10.0); // B69 - - double expectedResult = (4.0 * 8.0 + 5.0 * 9.0) / 10.0; - - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb); - fe.setCurrentRow(row); - CellValue cv = fe.evaluate(cell); - - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); - assertEquals(expectedResult, cv.getNumberValue(), 0.0); - } - - private static void addCell(HSSFSheet sheet, int rowIx, int colIx, - double value) { - sheet.createRow(rowIx).createCell((short) colIx).setCellValue(value); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java deleted file mode 100644 index 2d5408c76a..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java +++ /dev/null @@ -1,328 +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.io.FileInputStream; -import java.io.PrintStream; - -import junit.framework.Assert; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.functions.TestMathX; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; - -/** - * Tests formulas and operators as loaded from a test data spreadsheet.

    - * This class does not test implementors of Function and OperationEval in - * isolation. Much of the evaluation engine (i.e. HSSFFormulaEvaluator, ...) gets - * exercised as well. Tests for bug fixes and specific/tricky behaviour can be found in the - * corresponding test class (TestXxxx) of the target (Xxxx) implementor, - * where execution can be observed more easily. - * - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - */ -public final class TestFormulasFromSpreadsheet extends TestCase { - - private static final class Result { - public static final int SOME_EVALUATIONS_FAILED = -1; - public static final int ALL_EVALUATIONS_SUCCEEDED = +1; - public static final int NO_EVALUATIONS_FOUND = 0; - } - - /** - * This class defines constants for navigating around the test data spreadsheet used for these tests. - */ - private static final class SS { - - /** - * Name of the test spreadsheet (found in the standard test data folder) - */ - public final static String FILENAME = "FormulaEvalTestData.xls"; - /** - * Row (zero-based) in the test spreadsheet where the operator examples start. - */ - public static final int START_OPERATORS_ROW_INDEX = 22; // Row '23' - /** - * Row (zero-based) in the test spreadsheet where the function examples start. - */ - public static final int START_FUNCTIONS_ROW_INDEX = 87; // Row '88' - /** - * Index of the column that contains the function names - */ - public static final short COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' - - /** - * Used to indicate when there are no more functions left - */ - public static final String FUNCTION_NAMES_END_SENTINEL = ""; - - /** - * Index of the column where the test values start (for each function) - */ - public static final short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D' - - /** - * Each function takes 4 rows in the test spreadsheet - */ - public static final int NUMBER_OF_ROWS_PER_FUNCTION = 4; - } - - private HSSFWorkbook workbook; - private HSSFSheet sheet; - // Note - multiple failures are aggregated before ending. - // If one or more functions fail, a single AssertionFailedError is thrown at the end - private int _functionFailureCount; - private int _functionSuccessCount; - private int _evaluationFailureCount; - private int _evaluationSuccessCount; - - private static final HSSFCell getExpectedValueCell(HSSFRow row, short columnIndex) { - if (row == null) { - return null; - } - return row.getCell(columnIndex); - } - - - private static void confirmExpectedResult(String msg, HSSFCell expected, HSSFFormulaEvaluator.CellValue actual) { - if (expected == null) { - throw new AssertionFailedError(msg + " - Bad setup data expected value is null"); - } - if(actual == null) { - throw new AssertionFailedError(msg + " - actual value was null"); - } - - if (expected.getCellType() == HSSFCell.CELL_TYPE_STRING) { - String value = expected.getRichStringCellValue().getString(); - if (value.startsWith("#")) { - // TODO - this code never called - expected.setCellType(HSSFCell.CELL_TYPE_ERROR); - // expected.setCellErrorValue(...?); - } - } - - switch (expected.getCellType()) { - case HSSFCell.CELL_TYPE_BLANK: - assertEquals(msg, HSSFCell.CELL_TYPE_BLANK, actual.getCellType()); - break; - case HSSFCell.CELL_TYPE_BOOLEAN: - assertEquals(msg, HSSFCell.CELL_TYPE_BOOLEAN, actual.getCellType()); - assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue()); - break; - case HSSFCell.CELL_TYPE_ERROR: - assertEquals(msg, HSSFCell.CELL_TYPE_ERROR, actual.getCellType()); - if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values - assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue()); - } - break; - case HSSFCell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation - throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg); - case HSSFCell.CELL_TYPE_NUMERIC: - assertEquals(msg, HSSFCell.CELL_TYPE_NUMERIC, actual.getCellType()); - TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); -// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue()); -// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue()); -// assertTrue(msg, delta <= pctExpected); - break; - case HSSFCell.CELL_TYPE_STRING: - assertEquals(msg, HSSFCell.CELL_TYPE_STRING, actual.getCellType()); - assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getRichTextStringValue().getString()); - break; - } - } - - - protected void setUp() throws Exception { - if (workbook == null) { - String filePath = System.getProperty("HSSF.testdata.path")+ "/" + SS.FILENAME; - FileInputStream fin = new FileInputStream( filePath ); - workbook = new HSSFWorkbook( fin ); - sheet = workbook.getSheetAt( 0 ); - } - _functionFailureCount = 0; - _functionSuccessCount = 0; - _evaluationFailureCount = 0; - _evaluationSuccessCount = 0; - } - - public void testFunctionsFromTestSpreadsheet() { - - processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null); - processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null); - // example for debugging individual functions/operators: -// processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, "ConcatEval"); -// processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, "AVERAGE"); - - // confirm results - String successMsg = "There were " - + _evaluationSuccessCount + " successful evaluation(s) and " - + _functionSuccessCount + " function(s) without error"; - if(_functionFailureCount > 0) { - String msg = _functionFailureCount + " function(s) failed in " - + _evaluationFailureCount + " evaluation(s). " + successMsg; - throw new AssertionFailedError(msg); - } - if(false) { // normally no output for successful tests - System.out.println(getClass().getName() + ": " + successMsg); - } - } - - /** - * @param startRowIndex row index in the spreadsheet where the first function/operator is found - * @param testFocusFunctionName name of a single function/operator to test alone. - * Typically pass null to test all functions - */ - private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) { - - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook); - - int rowIndex = startRowIndex; - while (true) { - HSSFRow r = sheet.getRow(rowIndex); - String targetFunctionName = getTargetFunctionName(r); - if(targetFunctionName == null) { - throw new AssertionFailedError("Test spreadsheet cell empty on row (" - + (rowIndex+1) + "). Expected function name or '" - + SS.FUNCTION_NAMES_END_SENTINEL + "'"); - } - if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { - // found end of functions list - break; - } - if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { - - // expected results are on the row below - HSSFRow expectedValuesRow = sheet.getRow(rowIndex + 1); - if(expectedValuesRow == null) { - int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row - throw new AssertionFailedError("Missing expected values row for function '" - + targetFunctionName + " (row " + missingRowNum + ")"); - } - switch(processFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow)) { - case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break; - case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break; - default: - throw new RuntimeException("unexpected result"); - case Result.NO_EVALUATIONS_FOUND: // do nothing - } - } - rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION; - } - } - - /** - * - * @return a constant from the local Result class denoting whether there were any evaluation - * cases, and whether they all succeeded. - */ - private int processFunctionRow(HSSFFormulaEvaluator evaluator, String targetFunctionName, - HSSFRow formulasRow, HSSFRow expectedValuesRow) { - - int result = Result.NO_EVALUATIONS_FOUND; // so far - short endcolnum = formulasRow.getLastCellNum(); - evaluator.setCurrentRow(formulasRow); - - // iterate across the row for all the evaluation cases - for (short colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) { - HSSFCell c = formulasRow.getCell(colnum); - if (c == null || c.getCellType() != HSSFCell.CELL_TYPE_FORMULA) { - continue; - } - - HSSFFormulaEvaluator.CellValue actualValue = evaluator.evaluate(c); - - HSSFCell expectedValueCell = getExpectedValueCell(expectedValuesRow, colnum); - try { - confirmExpectedResult("Function '" + targetFunctionName + "': Formula: " + c.getCellFormula() + " @ " + formulasRow.getRowNum() + ":" + colnum, - expectedValueCell, actualValue); - _evaluationSuccessCount ++; - if(result != Result.SOME_EVALUATIONS_FAILED) { - result = Result.ALL_EVALUATIONS_SUCCEEDED; - } - } catch (AssertionFailedError e) { - _evaluationFailureCount ++; - printShortStackTrace(System.err, e); - result = Result.SOME_EVALUATIONS_FAILED; - } - } - return result; - } - - /** - * Useful to keep output concise when expecting many failures to be reported by this test case - */ - private static void printShortStackTrace(PrintStream ps, AssertionFailedError e) { - StackTraceElement[] stes = e.getStackTrace(); - - int startIx = 0; - // skip any top frames inside junit.framework.Assert - while(startIx= endIx) { - // something went wrong. just print the whole stack trace - e.printStackTrace(ps); - } - endIx -= 4; // skip 4 frames of reflection invocation - ps.println(e.toString()); - for(int i=startIx; inull if cell is missing, empty or blank - */ - private static String getTargetFunctionName(HSSFRow r) { - if(r == null) { - System.err.println("Warning - given null row, can't figure out function name"); - return null; - } - HSSFCell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME); - if(cell == null) { - System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name"); - return null; - } - if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) { - return null; - } - if(cell.getCellType() == HSSFCell.CELL_TYPE_STRING) { - return cell.getRichStringCellValue().getString(); - } - - throw new AssertionFailedError("Bad cell type for 'function name' column: (" - + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")"); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java deleted file mode 100755 index be8cef13fa..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java +++ /dev/null @@ -1,82 +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 junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.PercentPtg; -import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; - -/** - * Test for percent operator evaluator. - * - * @author Josh Micich - */ -public final class TestPercentEval extends TestCase { - - private static void confirm(ValueEval arg, double expectedResult) { - Eval[] args = { - arg, - }; - - PercentEval opEval = new PercentEval(new PercentPtg()); - double result = NumericFunctionInvoker.invoke(opEval, args, -1, (short)-1); - - assertEquals(expectedResult, result, 0); - } - - public void testBasic() { - confirm(new NumberEval(5), 0.05); - confirm(new NumberEval(3000), 30.0); - confirm(new NumberEval(-150), -1.5); - confirm(new StringEval("0.2"), 0.002); - confirm(BoolEval.TRUE, 0.01); - } - - public void testInSpreadSheet() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("Sheet1"); - HSSFRow row = sheet.createRow(0); - HSSFCell cell = row.createCell((short)0); - cell.setCellFormula("B1%"); - row.createCell((short)1).setCellValue(50.0); - - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); - fe.setCurrentRow(row); - CellValue cv; - try { - cv = fe.evaluate(cell); - } catch (RuntimeException e) { - if(e.getCause() instanceof NullPointerException) { - throw new AssertionFailedError("Identified bug 44608"); - } - // else some other unexpected error - throw e; - } - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); - assertEquals(0.5, cv.getNumberValue(), 0.0); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java deleted file mode 100755 index 724c54cd90..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java +++ /dev/null @@ -1,61 +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.AreaPtg; -import org.apache.poi.hssf.record.formula.UnaryPlusPtg; -import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker; - -import junit.framework.TestCase; - -/** - * Test for unary plus operator evaluator. - * - * @author Josh Micich - */ -public final class TestUnaryPlusEval extends TestCase { - - /** - * Test for bug observable at svn revision 618865 (5-Feb-2008)
    - * The code for handling column operands had been copy-pasted from the row handling code. - */ - public void testColumnOperand() { - - short firstRow = (short)8; - short lastRow = (short)12; - short colNum = (short)5; - AreaPtg areaPtg = new AreaPtg(firstRow, lastRow, colNum, colNum, false, false, false, false); - ValueEval[] values = { - new NumberEval(27), - new NumberEval(29), - new NumberEval(35), // value in row 10 - new NumberEval(37), - new NumberEval(38), - }; - Eval areaEval = new Area2DEval(areaPtg, values); - Eval[] args = { - areaEval, - }; - - double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(new UnaryPlusPtg()), args, 10, (short)20); - - assertEquals(35, result, 0); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/AbstractNumericTestCase.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/AbstractNumericTestCase.java deleted file mode 100644 index ef5b3add07..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/AbstractNumericTestCase.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 29, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - -import junit.framework.TestCase; - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public abstract class AbstractNumericTestCase extends TestCase { - - public static final double POS_ZERO = 1E-4; - public static final double DIFF_TOLERANCE_FACTOR = 1E-8; - - public void setUp() { - } - - public void tearDown() { - } - - /** - * Why doesnt JUnit have a method like this for doubles? - * The current impl (3.8.1) of Junit has a retar*** method - * for comparing doubles. DO NOT use that. - * TODO: This class should really be in an abstract super class - * to avoid code duplication across this project. - * @param message - * @param baseval - * @param checkval - */ - public static void assertEquals(String message, double baseval, double checkval, double almostZero, double diffToleranceFactor) { - double posZero = Math.abs(almostZero); - double negZero = -1 * posZero; - if (Double.isNaN(baseval)) { - assertTrue(message+": Expected " + baseval + " but was " + checkval - , Double.isNaN(baseval)); - } - else if (Double.isInfinite(baseval)) { - assertTrue(message+": Expected " + baseval + " but was " + checkval - , Double.isInfinite(baseval) && ((baseval<0) == (checkval<0))); - } - else { - assertTrue(message+": Expected " + baseval + " but was " + checkval - ,baseval != 0 - ? Math.abs(baseval - checkval) <= Math.abs(diffToleranceFactor * baseval) - : checkval < posZero && checkval > negZero); - } - } - - public static void assertEquals(String msg, double baseval, double checkval) { - assertEquals(msg, baseval, checkval, POS_ZERO, DIFF_TOLERANCE_FACTOR); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/AllIndividualFunctionEvaluationTests.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/AllIndividualFunctionEvaluationTests.java deleted file mode 100755 index 66d2a1d270..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/AllIndividualFunctionEvaluationTests.java +++ /dev/null @@ -1,53 +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 junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Direct tests for all implementors of Function. - * - * @author Josh Micich - */ -public final class AllIndividualFunctionEvaluationTests { - - // TODO - have this suite incorporated into a higher level one - public static Test suite() { - TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.functions"); - result.addTestSuite(TestAverage.class); - result.addTestSuite(TestCountFuncs.class); - result.addTestSuite(TestDate.class); - result.addTestSuite(TestFinanceLib.class); - result.addTestSuite(TestIndex.class); - result.addTestSuite(TestIsBlank.class); - result.addTestSuite(TestLen.class); - result.addTestSuite(TestMid.class); - result.addTestSuite(TestMathX.class); - result.addTestSuite(TestMatch.class); - result.addTestSuite(TestPmt.class); - result.addTestSuite(TestOffset.class); - result.addTestSuite(TestRowCol.class); - result.addTestSuite(TestSumproduct.class); - result.addTestSuite(TestStatsLib.class); - result.addTestSuite(TestTFunc.class); - result.addTestSuite(TestTrim.class); - result.addTestSuite(TestXYNumericFunction.class); - return result; - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java deleted file mode 100755 index a6e262b868..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java +++ /dev/null @@ -1,63 +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.AreaPtg; -import org.apache.poi.hssf.record.formula.ReferencePtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -import org.apache.poi.hssf.record.formula.eval.AreaEval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.Ref2DEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * Test helper class for creating mock Eval objects - * - * @author Josh Micich - */ -final class EvalFactory { - private static final NumberEval ZERO = new NumberEval(0); - - private EvalFactory() { - // no instances of this class - } - - /** - * Creates a dummy AreaEval (filled with zeros) - *

    - * nCols and nRows could have been derived - */ - public static AreaEval createAreaEval(String areaRefStr, int nCols, int nRows) { - int nValues = nCols * nRows; - ValueEval[] values = new ValueEval[nValues]; - for (int i = 0; i < nValues; i++) { - values[i] = ZERO; - } - - return new Area2DEval(new AreaPtg(areaRefStr), values); - } - - /** - * Creates a single RefEval (with value zero) - */ - public static RefEval createRefEval(String refStr) { - return new Ref2DEval(new ReferencePtg(refStr), ZERO); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java deleted file mode 100755 index d477231349..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java +++ /dev/null @@ -1,126 +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 junit.framework.AssertionFailedError; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.OperationEval; - -/** - * Test helper class for invoking functions with numeric results. - * - * @author Josh Micich - */ -public final class NumericFunctionInvoker { - - private NumericFunctionInvoker() { - // no instances of this class - } - - private static final class NumericEvalEx extends Exception { - public NumericEvalEx(String msg) { - super(msg); - } - } - - /** - * Invokes the specified function with the arguments. - *

    - * Assumes that the cell coordinate parameters of - * Function.evaluate(args, srcCellRow, srcCellCol) - * are not required. - *

    - * This method cannot be used for confirming error return codes. Any non-numeric evaluation - * result causes the current junit test to fail. - */ - public static double invoke(Function f, Eval[] args) { - try { - return invokeInternal(f, args, -1, -1); - } catch (NumericEvalEx e) { - throw new AssertionFailedError("Evaluation of function (" + f.getClass().getName() - + ") failed: " + e.getMessage()); - } - - } - /** - * Invokes the specified operator with the arguments. - *

    - * This method cannot be used for confirming error return codes. Any non-numeric evaluation - * result causes the current junit test to fail. - */ - public static double invoke(OperationEval f, Eval[] args, int srcCellRow, int srcCellCol) { - try { - return invokeInternal(f, args, srcCellRow, srcCellCol); - } catch (NumericEvalEx e) { - throw new AssertionFailedError("Evaluation of function (" + f.getClass().getName() - + ") failed: " + e.getMessage()); - } - - } - /** - * Formats nicer error messages for the junit output - */ - private static double invokeInternal(Object target, Eval[] args, int srcCellRow, int srcCellCol) - throws NumericEvalEx { - Eval evalResult; - // TODO - make OperationEval extend Function - if (target instanceof Function) { - Function ff = (Function) target; - evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol); - } else { - OperationEval ff = (OperationEval) target; - evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol); - } - - if(evalResult == null) { - throw new NumericEvalEx("Result object was null"); - } - if(evalResult instanceof ErrorEval) { - ErrorEval ee = (ErrorEval) evalResult; - throw new NumericEvalEx(formatErrorMessage(ee)); - } - if(!(evalResult instanceof NumericValueEval)) { - throw new NumericEvalEx("Result object type (" + evalResult.getClass().getName() - + ") is invalid. Expected implementor of (" - + NumericValueEval.class.getName() + ")"); - } - - NumericValueEval result = (NumericValueEval) evalResult; - return result.getNumberValue(); - } - private static String formatErrorMessage(ErrorEval ee) { - if(errorCodesAreEqual(ee, ErrorEval.FUNCTION_NOT_IMPLEMENTED)) { - return "Function not implemented"; - } - if(errorCodesAreEqual(ee, ErrorEval.VALUE_INVALID)) { - return "Error code: #VALUE! (invalid value)"; - } - return "Error code=" + ee.getErrorCode(); - } - private static boolean errorCodesAreEqual(ErrorEval a, ErrorEval b) { - if(a==b) { - return true; - } - return a.getErrorCode() == b.getErrorCode(); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java deleted file mode 100755 index 4f0e5fff2c..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java +++ /dev/null @@ -1,103 +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 junit.framework.TestCase; - -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -/** - * Tests for Excel function AVERAGE() - * - * @author Josh Micich - */ -public final class TestAverage extends TestCase { - - - private static Eval invokeAverage(Eval[] args) { - return new Average().evaluate(args, -1, (short)-1); - } - - private void confirmAverage(Eval[] args, double expected) { - Eval result = invokeAverage(args); - assertEquals(NumberEval.class, result.getClass()); - assertEquals(expected, ((NumberEval)result).getNumberValue(), 0); - } - - private void confirmAverage(Eval[] args, ErrorEval expectedError) { - Eval result = invokeAverage(args); - assertEquals(ErrorEval.class, result.getClass()); - assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); - } - - public void testBasic() { - - ValueEval[] values = { - new NumberEval(1), - new NumberEval(2), - new NumberEval(3), - new NumberEval(4), - }; - - confirmAverage(values, 2.5); - - values = new ValueEval[] { - new NumberEval(1), - new NumberEval(2), - BlankEval.INSTANCE, - new NumberEval(3), - BlankEval.INSTANCE, - new NumberEval(4), - BlankEval.INSTANCE, - }; - - confirmAverage(values, 2.5); - } - - /** - * Valid cases where values are not pure numbers - */ - public void testUnusualArgs() { - ValueEval[] values = { - new NumberEval(1), - new NumberEval(2), - BoolEval.TRUE, - BoolEval.FALSE, - }; - - confirmAverage(values, 1.0); - - } - - // currently disabled because MultiOperandNumericFunction.getNumberArray(Eval[], int, short) - // does not handle error values properly yet - public void XtestErrors() { - ValueEval[] values = { - new NumberEval(1), - ErrorEval.NAME_INVALID, - new NumberEval(3), - ErrorEval.DIV_ZERO, - }; - confirmAverage(values, ErrorEval.NAME_INVALID); - - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java deleted file mode 100755 index ae93a2d41b..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java +++ /dev/null @@ -1,150 +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 junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.ReferencePtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.Ref2DEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * Test cases for COUNT(), COUNTA() COUNTIF(), COUNTBLANK() - * - * @author Josh Micich - */ -public final class TestCountFuncs extends TestCase { - - public TestCountFuncs(String testName) { - super(testName); - } - - public void testCountA() { - - Eval[] args; - - args = new Eval[] { - new NumberEval(0), - }; - confirmCountA(1, args); - - args = new Eval[] { - new NumberEval(0), - new NumberEval(0), - new StringEval(""), - }; - confirmCountA(3, args); - - args = new Eval[] { - EvalFactory.createAreaEval("D2:F5", 3, 4), - }; - confirmCountA(12, args); - - args = new Eval[] { - EvalFactory.createAreaEval("D1:F5", 3, 5), // 15 - EvalFactory.createRefEval("A1"), - EvalFactory.createAreaEval("A1:F6", 7, 6), // 42 - new NumberEval(0), - }; - confirmCountA(59, args); - } - - public void testCountIf() { - - AreaEval range; - ValueEval[] values; - - // when criteria is a boolean value - values = new ValueEval[] { - new NumberEval(0), - new StringEval("TRUE"), // note - does not match boolean TRUE - BoolEval.TRUE, - BoolEval.FALSE, - BoolEval.TRUE, - BlankEval.INSTANCE, - }; - range = createAreaEval("A1:B2", values); - confirmCountIf(2, range, BoolEval.TRUE); - - // when criteria is numeric - values = new ValueEval[] { - new NumberEval(0), - new StringEval("2"), - new StringEval("2.001"), - new NumberEval(2), - new NumberEval(2), - BoolEval.TRUE, - BlankEval.INSTANCE, - }; - range = createAreaEval("A1:B2", values); - confirmCountIf(3, range, new NumberEval(2)); - // note - same results when criteria is a string that parses as the number with the same value - confirmCountIf(3, range, new StringEval("2.00")); - - if (false) { // not supported yet: - // when criteria is an expression (starting with a comparison operator) - confirmCountIf(4, range, new StringEval(">1")); - } - } - /** - * special case where the criteria argument is a cell reference - */ - public void testCountIfWithCriteriaReference() { - - ValueEval[] values = { - new NumberEval(22), - new NumberEval(25), - new NumberEval(21), - new NumberEval(25), - new NumberEval(25), - new NumberEval(25), - }; - Area2DEval arg0 = new Area2DEval(new AreaPtg("C1:C6"), values); - - Ref2DEval criteriaArg = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(25)); - Eval[] args= { arg0, criteriaArg, }; - - double actual = NumericFunctionInvoker.invoke(new Countif(), args); - assertEquals(4, actual, 0D); - } - - - private static AreaEval createAreaEval(String areaRefStr, ValueEval[] values) { - return new Area2DEval(new AreaPtg(areaRefStr), values); - } - - private static void confirmCountA(int expected, Eval[] args) { - double result = NumericFunctionInvoker.invoke(new Counta(), args); - assertEquals(expected, result, 0); - } - private static void confirmCountIf(int expected, AreaEval range, Eval criteria) { - - Eval[] args = { range, criteria, }; - double result = NumericFunctionInvoker.invoke(new Countif(), args); - assertEquals(expected, result, 0); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestDate.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestDate.java deleted file mode 100644 index 2c5e152ab8..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestDate.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Created on Sep 11, 2007 - * - * The Copyright statements and Licenses for the commons application may be - * found in the file LICENSE.txt - */ - -package org.apache.poi.hssf.record.formula.functions; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; - -/** - * @author Pavel Krupets (pkrupets at palmtreebusiness dot com) - */ -public class TestDate extends TestCase { - public void setUp() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet("new sheet"); - HSSFRow row1 = sheet.createRow((short) 0); - - this.cell11 = row1.createCell((short) 0); - - this.evaluator = new HSSFFormulaEvaluator(sheet, wb); - this.evaluator.setCurrentRow(row1); - } - - /** - * Test disabled pending a fix in the formula parser - */ - public void DISABLEDtestSomeArgumentsMissing() throws Exception { - this.cell11.setCellFormula("DATE(, 1, 0)"); - assertEquals(0.0, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(, 1, 1)"); - assertEquals(1.0, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - } - - public void testValid() throws Exception { - this.cell11.setCellType(HSSFCell.CELL_TYPE_FORMULA); - - this.cell11.setCellFormula("DATE(1900, 1, 1)"); - assertEquals(1, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1900, 1, 32)"); - assertEquals(32, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1900, 222, 1)"); - assertEquals(6727, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1900, 2, 0)"); - assertEquals(31, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(2000, 1, 222)"); - assertEquals(36747.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(2007, 1, 1)"); - assertEquals(39083, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - } - - public void testBugDate() { - this.cell11.setCellFormula("DATE(1900, 2, 29)"); - assertEquals(60, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1900, 2, 30)"); - assertEquals(61, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1900, 1, 222)"); - assertEquals(222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1900, 1, 2222)"); - assertEquals(2222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1900, 1, 22222)"); - assertEquals(22222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - } - - public void testPartYears() { - this.cell11.setCellFormula("DATE(4, 1, 1)"); - assertEquals(1462.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(14, 1, 1)"); - assertEquals(5115.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(104, 1, 1)"); - assertEquals(37987.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - - this.cell11.setCellFormula("DATE(1004, 1, 1)"); - assertEquals(366705.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); - } - - private HSSFCell cell11; - private HSSFFormulaEvaluator evaluator; -} - diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestFinanceLib.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestFinanceLib.java deleted file mode 100644 index 4dfe1fbb52..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestFinanceLib.java +++ /dev/null @@ -1,202 +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 23, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class TestFinanceLib extends AbstractNumericTestCase { - - public void testFv() { - double f, r, y, p, x; - int n; - boolean t = false; - - r = 0; n = 3; y = 2; p = 7; t = true; - f = FinanceLib.fv(r, n, y, p, t); - x = -13; - assertEquals("fv ", x, f); - - r = 1; n = 10; y = 100; p = 10000; t = false; - f = FinanceLib.fv(r, n, y, p, t); - x = -10342300; - assertEquals("fv ", x, f); - - r = 1; n = 10; y = 100; p = 10000; t = true; - f = FinanceLib.fv(r, n, y, p, t); - x = -10444600; - assertEquals("fv ", x, f); - - r = 2; n = 12; y = 120; p = 12000; t = false; - f = FinanceLib.fv(r, n, y, p, t); - x = -6409178400d; - assertEquals("fv ", x, f); - - r = 2; n = 12; y = 120; p = 12000; t = true; - f = FinanceLib.fv(r, n, y, p, t); - x = -6472951200d; - assertEquals("fv ", x, f); - - // cross tests with pv - r = 2.95; n = 13; y = 13000; p = -4406.78544294496; t = false; - f = FinanceLib.fv(r, n, y, p, t); - x = 333891.230010986; // as returned by excel - assertEquals("fv ", x, f); - - r = 2.95; n = 13; y = 13000; p = -17406.7852148156; t = true; - f = FinanceLib.fv(r, n, y, p, t); - x = 333891.230102539; // as returned by excel - assertEquals("fv ", x, f); - - } - public void testNpv() { - double r, v[], npv, x; - - r = 1; v = new double[]{100, 200, 300, 400}; - npv = FinanceLib.npv(r, v); - x = 162.5; - assertEquals("npv ", x, npv); - - r = 2.5; v = new double[]{1000, 666.66666, 333.33, 12.2768416}; - npv = FinanceLib.npv(r, v); - x = 347.99232604144827; - assertEquals("npv ", x, npv); - - r = 12.33333; v = new double[]{1000, 0, -900, -7777.5765}; - npv = FinanceLib.npv(r, v); - x = 74.3742433377061; - assertEquals("npv ", x, npv); - - r = 0.05; v = new double[]{200000, 300000.55, 400000, 1000000, 6000000, 7000000, -300000}; - npv = FinanceLib.npv(r, v); - x = 11342283.4233124; - assertEquals("npv ", x, npv); - } - public void testPmt() { - double f, r, y, p, x; - int n; - boolean t = false; - - r = 0; n = 3; p = 2; f = 7; t = true; - y = FinanceLib.pmt(r, n, p, f, t); - x = -3; - assertEquals("pmt ", x, y); - - // cross check with pv - r = 1; n = 10; p = -109.66796875; f = 10000; t = false; - y = FinanceLib.pmt(r, n, p, f, t); - x = 100; - assertEquals("pmt ", x, y); - - r = 1; n = 10; p = -209.5703125; f = 10000; t = true; - y = FinanceLib.pmt(r, n, p, f, t); - x = 100; - assertEquals("pmt ", x, y); - - // cross check with fv - r = 2; n = 12; f = -6409178400d; p = 12000; t = false; - y = FinanceLib.pmt(r, n, p, f, t); - x = 120; - assertEquals("pmt ", x, y); - - r = 2; n = 12; f = -6472951200d; p = 12000; t = true; - y = FinanceLib.pmt(r, n, p, f, t); - x = 120; - assertEquals("pmt ", x, y); - } - - public void testPv() { - double f, r, y, p, x; - int n; - boolean t = false; - - r = 0; n = 3; y = 2; f = 7; t = true; - f = FinanceLib.pv(r, n, y, f, t); - x = -13; - assertEquals("pv ", x, f); - - r = 1; n = 10; y = 100; f = 10000; t = false; - p = FinanceLib.pv(r, n, y, f, t); - x = -109.66796875; - assertEquals("pv ", x, p); - - r = 1; n = 10; y = 100; f = 10000; t = true; - p = FinanceLib.pv(r, n, y, f, t); - x = -209.5703125; - assertEquals("pv ", x, p); - - r = 2.95; n = 13; y = 13000; f = 333891.23; t = false; - p = FinanceLib.pv(r, n, y, f, t); - x = -4406.78544294496; - assertEquals("pv ", x, p); - - r = 2.95; n = 13; y = 13000; f = 333891.23; t = true; - p = FinanceLib.pv(r, n, y, f, t); - x = -17406.7852148156; - assertEquals("pv ", x, p); - - // cross tests with fv - r = 2; n = 12; y = 120; f = -6409178400d; t = false; - p = FinanceLib.pv(r, n, y, f, t); - x = 12000; - assertEquals("pv ", x, p); - - r = 2; n = 12; y = 120; f = -6472951200d; t = true; - p = FinanceLib.pv(r, n, y, f, t); - x = 12000; - assertEquals("pv ", x, p); - - } - - public void testNper() { - double f, r, y, p, x, n; - boolean t = false; - - r = 0; y = 7; p = 2; f = 3; t = false; - n = FinanceLib.nper(r, y, p, f, t); - x = -0.71428571429; // can you believe it? excel returns nper as a fraction!?? - assertEquals("nper ", x, n); - - // cross check with pv - r = 1; y = 100; p = -109.66796875; f = 10000; t = false; - n = FinanceLib.nper(r, y, p, f, t); - x = 10; - assertEquals("nper ", x, n); - - r = 1; y = 100; p = -209.5703125; f = 10000; t = true; - n = FinanceLib.nper(r, y, p, f, t); - x = 10; - assertEquals("nper ", x, n); - - // cross check with fv - r = 2; y = 120; f = -6409178400d; p = 12000; t = false; - n = FinanceLib.nper(r, y, p, f, t); - x = 12; - assertEquals("nper ", x, n); - - r = 2; y = 120; f = -6472951200d; p = 12000; t = true; - n = FinanceLib.nper(r, y, p, f, t); - x = 12; - assertEquals("nper ", x, n); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java deleted file mode 100755 index 902c4122ef..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java +++ /dev/null @@ -1,89 +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 junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * Tests for the INDEX() function - * - * @author Josh Micich - */ -public final class TestIndex extends TestCase { - - public TestIndex(String testName) { - super(testName); - } - - private static final double[] TEST_VALUES0 = { - 1, 2, - 3, 4, - 5, 6, - 7, 8, - 9, 10, - 11, 12, - 13, // excess array element. TODO - Area2DEval currently has no validation to ensure correct size of values array - }; - - /** - * For the case when the first argument to INDEX() is an area reference - */ - public void testEvaluateAreaReference() { - - double[] values = TEST_VALUES0; - confirmAreaEval("C1:D6", values, 4, 1, 7); - confirmAreaEval("C1:D6", values, 6, 2, 12); - confirmAreaEval("C1:D6", values, 3, -1, 5); - - // now treat same data as 3 columns, 4 rows - confirmAreaEval("C10:E13", values, 2, 2, 5); - confirmAreaEval("C10:E13", values, 4, -1, 10); - } - - /** - * @param areaRefString in Excel notation e.g. 'D2:E97' - * @param dValues array of evaluated values for the area reference - * @param rowNum 1-based - * @param colNum 1-based, pass -1 to signify argument not present - */ - private static void confirmAreaEval(String areaRefString, double[] dValues, - int rowNum, int colNum, double expectedResult) { - ValueEval[] values = new ValueEval[dValues.length]; - for (int i = 0; i < values.length; i++) { - values[i] = new NumberEval(dValues[i]); - } - Area2DEval arg0 = new Area2DEval(new AreaPtg(areaRefString), values); - - Eval[] args; - if (colNum > 0) { - args = new Eval[] { arg0, new NumberEval(rowNum), new NumberEval(colNum), }; - } else { - args = new Eval[] { arg0, new NumberEval(rowNum), }; - } - - double actual = NumericFunctionInvoker.invoke(new Index(), args); - assertEquals(expectedResult, actual, 0D); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestIsBlank.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestIsBlank.java deleted file mode 100755 index 7ce2bd245b..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestIsBlank.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ==================================================================== - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -==================================================================== */ - -package org.apache.poi.hssf.record.formula.functions; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; -/** - * Tests for Excel function ISBLANK() - * - * @author Josh Micich - */ -public final class TestIsBlank extends TestCase { - - - - public void test3DArea() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet1 = wb.createSheet(); - wb.setSheetName(0, "Sheet1"); - wb.createSheet(); - wb.setSheetName(1, "Sheet2"); - HSSFRow row = sheet1.createRow(0); - HSSFCell cell = row.createCell((short)0); - - - cell.setCellFormula("isblank(Sheet2!A1:A1)"); - - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb); - fe.setCurrentRow(row); - CellValue result = fe.evaluate(cell); - assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType()); - assertEquals(true, result.getBooleanValue()); - - cell.setCellFormula("isblank(D7:D7)"); - - result = fe.evaluate(cell); - assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType()); - assertEquals(true, result.getBooleanValue()); - - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestLen.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestLen.java deleted file mode 100755 index a96fb4e2b0..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestLen.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. -==================================================================== */ - -package org.apache.poi.hssf.record.formula.functions; - -import junit.framework.TestCase; - -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -/** - * Tests for Excel function LEN() - * - * @author Josh Micich - */ -public final class TestLen extends TestCase { - - - private static Eval invokeLen(Eval text) { - Eval[] args = new Eval[] { text, }; - return new Len().evaluate(args, -1, (short)-1); - } - - private void confirmLen(Eval text, int expected) { - Eval result = invokeLen(text); - assertEquals(NumberEval.class, result.getClass()); - assertEquals(expected, ((NumberEval)result).getNumberValue(), 0); - } - - private void confirmLen(Eval text, ErrorEval expectedError) { - Eval result = invokeLen(text); - assertEquals(ErrorEval.class, result.getClass()); - assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); - } - - public void testBasic() { - - confirmLen(new StringEval("galactic"), 8); - } - - /** - * Valid cases where text arg is not exactly a string - */ - public void testUnusualArgs() { - - // text (first) arg type is number, other args are strings with fractional digits - confirmLen(new NumberEval(123456), 6); - confirmLen(BoolEval.FALSE, 5); - confirmLen(BoolEval.TRUE, 4); - confirmLen(BlankEval.INSTANCE, 0); - } - - public void testErrors() { - confirmLen(ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestLookupFunctionsFromSpreadsheet.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestLookupFunctionsFromSpreadsheet.java deleted file mode 100644 index 071ca0f7d8..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestLookupFunctionsFromSpreadsheet.java +++ /dev/null @@ -1,385 +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.io.FileInputStream; -import java.io.IOException; -import java.io.PrintStream; - -import junit.framework.Assert; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; -import org.apache.poi.hssf.util.CellReference; - -/** - * Tests lookup functions (VLOOKUP, HLOOKUP, LOOKUP, MATCH) as loaded from a test data spreadsheet.

    - * These tests have been separated from the common function and operator tests because the lookup - * functions have more complex test cases and test data setup. - * - * Tests for bug fixes and specific/tricky behaviour can be found in the corresponding test class - * (TestXxxx) of the target (Xxxx) implementor, where execution can be observed - * more easily. - * - * @author Josh Micich - */ -public final class TestLookupFunctionsFromSpreadsheet extends TestCase { - - private static final class Result { - public static final int SOME_EVALUATIONS_FAILED = -1; - public static final int ALL_EVALUATIONS_SUCCEEDED = +1; - public static final int NO_EVALUATIONS_FOUND = 0; - } - - /** - * This class defines constants for navigating around the test data spreadsheet used for these tests. - */ - private static final class SS { - - /** Name of the test spreadsheet (found in the standard test data folder) */ - public final static String FILENAME = "LookupFunctionsTestCaseData.xls"; - - /** Name of the first sheet in the spreadsheet (contains comments) */ - public final static String README_SHEET_NAME = "Read Me"; - - - /** Row (zero-based) in each sheet where the evaluation cases start. */ - public static final int START_TEST_CASES_ROW_INDEX = 4; // Row '5' - /** Index of the column that contains the function names */ - public static final short COLUMN_INDEX_MARKER = 0; // Column 'A' - public static final short COLUMN_INDEX_EVALUATION = 1; // Column 'B' - public static final short COLUMN_INDEX_EXPECTED_RESULT = 2; // Column 'C' - public static final short COLUMN_ROW_COMMENT = 3; // Column 'D' - - /** Used to indicate when there are no more test cases on the current sheet */ - public static final String TEST_CASES_END_MARKER = ""; - /** Used to indicate that the test on the current row should be ignored */ - public static final String SKIP_CURRENT_TEST_CASE_MARKER = ""; - - } - - // Note - multiple failures are aggregated before ending. - // If one or more functions fail, a single AssertionFailedError is thrown at the end - private int _sheetFailureCount; - private int _sheetSuccessCount; - private int _evaluationFailureCount; - private int _evaluationSuccessCount; - - - - private static void confirmExpectedResult(String msg, HSSFCell expected, HSSFFormulaEvaluator.CellValue actual) { - if (expected == null) { - throw new AssertionFailedError(msg + " - Bad setup data expected value is null"); - } - if(actual == null) { - throw new AssertionFailedError(msg + " - actual value was null"); - } - if(expected.getCellType() == HSSFCell.CELL_TYPE_ERROR) { - confirmErrorResult(msg, expected.getErrorCellValue(), actual); - return; - } - if(actual.getCellType() == HSSFCell.CELL_TYPE_ERROR) { - throw unexpectedError(msg, expected, actual.getErrorValue()); - } - if(actual.getCellType() != expected.getCellType()) { - throw wrongTypeError(msg, expected, actual); - } - - - switch (expected.getCellType()) { - case HSSFCell.CELL_TYPE_BOOLEAN: - assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue()); - break; - case HSSFCell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation - throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg); - case HSSFCell.CELL_TYPE_NUMERIC: - assertEquals(expected.getNumericCellValue(), actual.getNumberValue(), 0.0); - break; - case HSSFCell.CELL_TYPE_STRING: - assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getRichTextStringValue().getString()); - break; - } - } - - - private static AssertionFailedError wrongTypeError(String msgPrefix, HSSFCell expectedCell, CellValue actualValue) { - return new AssertionFailedError(msgPrefix + " Result type mismatch. Evaluated result was " - + formatValue(actualValue) - + " but the expected result was " - + formatValue(expectedCell) - ); - } - private static AssertionFailedError unexpectedError(String msgPrefix, HSSFCell expected, int actualErrorCode) { - return new AssertionFailedError(msgPrefix + " Error code (" - + ErrorEval.getText(actualErrorCode) - + ") was evaluated, but the expected result was " - + formatValue(expected) - ); - } - - - private static void confirmErrorResult(String msgPrefix, int expectedErrorCode, CellValue actual) { - if(actual.getCellType() != HSSFCell.CELL_TYPE_ERROR) { - throw new AssertionFailedError(msgPrefix + " Expected cell error (" - + ErrorEval.getText(expectedErrorCode) + ") but actual value was " - + formatValue(actual)); - } - if(expectedErrorCode != actual.getErrorValue()) { - throw new AssertionFailedError(msgPrefix + " Expected cell error code (" - + ErrorEval.getText(expectedErrorCode) - + ") but actual error code was (" - + ErrorEval.getText(actual.getErrorValue()) - + ")"); - } - } - - - private static String formatValue(HSSFCell expecedCell) { - switch (expecedCell.getCellType()) { - case HSSFCell.CELL_TYPE_BLANK: return ""; - case HSSFCell.CELL_TYPE_BOOLEAN: return String.valueOf(expecedCell.getBooleanCellValue()); - case HSSFCell.CELL_TYPE_NUMERIC: return String.valueOf(expecedCell.getNumericCellValue()); - case HSSFCell.CELL_TYPE_STRING: return expecedCell.getRichStringCellValue().getString(); - } - throw new RuntimeException("Unexpected cell type of expected value (" + expecedCell.getCellType() + ")"); - } - private static String formatValue(CellValue actual) { - switch (actual.getCellType()) { - case HSSFCell.CELL_TYPE_BLANK: return ""; - case HSSFCell.CELL_TYPE_BOOLEAN: return String.valueOf(actual.getBooleanValue()); - case HSSFCell.CELL_TYPE_NUMERIC: return String.valueOf(actual.getNumberValue()); - case HSSFCell.CELL_TYPE_STRING: return actual.getRichTextStringValue().getString(); - } - throw new RuntimeException("Unexpected cell type of evaluated value (" + actual.getCellType() + ")"); - } - - - protected void setUp() throws Exception { - _sheetFailureCount = 0; - _sheetSuccessCount = 0; - _evaluationFailureCount = 0; - _evaluationSuccessCount = 0; - } - - public void testFunctionsFromTestSpreadsheet() { - String filePath = System.getProperty("HSSF.testdata.path")+ "/" + SS.FILENAME; - HSSFWorkbook workbook; - try { - FileInputStream fin = new FileInputStream( filePath ); - workbook = new HSSFWorkbook( fin ); - } catch (IOException e) { - throw new RuntimeException(e); - } - - confirmReadMeSheet(workbook); - int nSheets = workbook.getNumberOfSheets(); - for(int i=1; i< nSheets; i++) { - int sheetResult = processTestSheet(workbook, i, workbook.getSheetName(i)); - switch(sheetResult) { - case Result.ALL_EVALUATIONS_SUCCEEDED: _sheetSuccessCount ++; break; - case Result.SOME_EVALUATIONS_FAILED: _sheetFailureCount ++; break; - } - } - - // confirm results - String successMsg = "There were " - + _sheetSuccessCount + " successful sheets(s) and " - + _evaluationSuccessCount + " function(s) without error"; - if(_sheetFailureCount > 0) { - String msg = _sheetFailureCount + " sheets(s) failed with " - + _evaluationFailureCount + " evaluation(s). " + successMsg; - throw new AssertionFailedError(msg); - } - if(false) { // normally no output for successful tests - System.out.println(getClass().getName() + ": " + successMsg); - } - } - - private int processTestSheet(HSSFWorkbook workbook, int sheetIndex, String sheetName) { - HSSFSheet sheet = workbook.getSheetAt(sheetIndex); - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook); - int maxRows = sheet.getLastRowNum()+1; - int result = Result.NO_EVALUATIONS_FOUND; // so far - - String currentGroupComment = null; - for(int rowIndex=SS.START_TEST_CASES_ROW_INDEX; rowIndex= endIx) { - // something went wrong. just print the whole stack trace - e.printStackTrace(ps); - } - endIx -= 4; // skip 4 frames of reflection invocation - ps.println(e.toString()); - for(int i=startIx; inull if cell is missing, empty or blank - */ - private static String getCellTextValue(HSSFRow r, int colIndex, String columnName) { - if(r == null) { - return null; - } - HSSFCell cell = r.getCell((short) colIndex); - if(cell == null) { - return null; - } - if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) { - return null; - } - if(cell.getCellType() == HSSFCell.CELL_TYPE_STRING) { - return cell.getRichStringCellValue().getString(); - } - - throw new RuntimeException("Bad cell type for '" + columnName + "' column: (" - + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")"); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMatch.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMatch.java deleted file mode 100755 index d275e5f333..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMatch.java +++ /dev/null @@ -1,215 +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 junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -import org.apache.poi.hssf.record.formula.eval.AreaEval; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -/** - * Test cases for MATCH() - * - * @author Josh Micich - */ -public final class TestMatch extends TestCase { - /** less than or equal to */ - private static final NumberEval MATCH_LARGEST_LTE = new NumberEval(1); - private static final NumberEval MATCH_EXACT = new NumberEval(0); - /** greater than or equal to */ - private static final NumberEval MATCH_SMALLEST_GTE = new NumberEval(-1); - - - private static Eval invokeMatch(Eval lookup_value, Eval lookup_array, Eval match_type) { - Eval[] args = { lookup_value, lookup_array, match_type, }; - return new Match().evaluate(args, -1, (short)-1); - } - private static void confirmInt(int expected, Eval actualEval) { - if(!(actualEval instanceof NumericValueEval)) { - fail("Expected numeric result"); - } - NumericValueEval nve = (NumericValueEval)actualEval; - assertEquals(expected, nve.getNumberValue(), 0); - } - /** - * Convenience method - * @return new Area2DEval(new AreaPtg(ref), values) - */ - private static AreaEval createAreaEval(String ref, ValueEval[] values) { - return new Area2DEval(new AreaPtg(ref), values); - } - - public void testSimpleNumber() { - - ValueEval[] values = { - new NumberEval(4), - new NumberEval(5), - new NumberEval(10), - new NumberEval(10), - new NumberEval(25), - }; - - AreaEval ae = createAreaEval("A1:A5", values); - - confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE)); - confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_EXACT)); - confirmInt(4, invokeMatch(new NumberEval(10), ae, MATCH_LARGEST_LTE)); - confirmInt(3, invokeMatch(new NumberEval(10), ae, MATCH_EXACT)); - confirmInt(4, invokeMatch(new NumberEval(20), ae, MATCH_LARGEST_LTE)); - assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(20), ae, MATCH_EXACT)); - } - - public void testReversedNumber() { - - ValueEval[] values = { - new NumberEval(25), - new NumberEval(10), - new NumberEval(10), - new NumberEval(10), - new NumberEval(4), - }; - - AreaEval ae = createAreaEval("A1:A5", values); - - confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_SMALLEST_GTE)); - confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_EXACT)); - confirmInt(4, invokeMatch(new NumberEval(9), ae, MATCH_SMALLEST_GTE)); - confirmInt(1, invokeMatch(new NumberEval(20), ae, MATCH_SMALLEST_GTE)); - assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(20), ae, MATCH_EXACT)); - assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(26), ae, MATCH_SMALLEST_GTE)); - } - - public void testSimpleString() { - - ValueEval[] values = { - new StringEval("Albert"), - new StringEval("Charles"), - new StringEval("Ed"), - new StringEval("Greg"), - new StringEval("Ian"), - }; - - AreaEval ae = createAreaEval("A1:A5", values); - - // Note String comparisons are case insensitive - confirmInt(3, invokeMatch(new StringEval("Ed"), ae, MATCH_LARGEST_LTE)); - confirmInt(3, invokeMatch(new StringEval("eD"), ae, MATCH_LARGEST_LTE)); - confirmInt(3, invokeMatch(new StringEval("Ed"), ae, MATCH_EXACT)); - confirmInt(3, invokeMatch(new StringEval("ed"), ae, MATCH_EXACT)); - confirmInt(4, invokeMatch(new StringEval("Hugh"), ae, MATCH_LARGEST_LTE)); - assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Hugh"), ae, MATCH_EXACT)); - } - - public void testSimpleBoolean() { - - ValueEval[] values = { - BoolEval.FALSE, - BoolEval.FALSE, - BoolEval.TRUE, - BoolEval.TRUE, - }; - - AreaEval ae = createAreaEval("A1:A4", values); - - // Note String comparisons are case insensitive - confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE)); - confirmInt(1, invokeMatch(BoolEval.FALSE, ae, MATCH_EXACT)); - confirmInt(4, invokeMatch(BoolEval.TRUE, ae, MATCH_LARGEST_LTE)); - confirmInt(3, invokeMatch(BoolEval.TRUE, ae, MATCH_EXACT)); - } - - public void testHeterogeneous() { - - ValueEval[] values = { - new NumberEval(4), - BoolEval.FALSE, - new NumberEval(5), - new StringEval("Albert"), - BoolEval.FALSE, - BoolEval.TRUE, - new NumberEval(10), - new StringEval("Charles"), - new StringEval("Ed"), - new NumberEval(10), - new NumberEval(25), - BoolEval.TRUE, - new StringEval("Ed"), - }; - - AreaEval ae = createAreaEval("A1:A13", values); - - assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Aaron"), ae, MATCH_LARGEST_LTE)); - - confirmInt(5, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE)); - confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_EXACT)); - confirmInt(3, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE)); - confirmInt(3, invokeMatch(new NumberEval(5), ae, MATCH_EXACT)); - - confirmInt(8, invokeMatch(new StringEval("CHARLES"), ae, MATCH_EXACT)); - - confirmInt(4, invokeMatch(new StringEval("Ben"), ae, MATCH_LARGEST_LTE)); - - confirmInt(13, invokeMatch(new StringEval("ED"), ae, MATCH_LARGEST_LTE)); - confirmInt(9, invokeMatch(new StringEval("ED"), ae, MATCH_EXACT)); - - confirmInt(13, invokeMatch(new StringEval("Hugh"), ae, MATCH_LARGEST_LTE)); - assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Hugh"), ae, MATCH_EXACT)); - - confirmInt(11, invokeMatch(new NumberEval(30), ae, MATCH_LARGEST_LTE)); - confirmInt(12, invokeMatch(BoolEval.TRUE, ae, MATCH_LARGEST_LTE)); - } - - - /** - * Ensures that the match_type argument can be an AreaEval.
    - * Bugzilla 44421 - */ - public void testMatchArgTypeArea() { - - ValueEval[] values = { - new NumberEval(4), - new NumberEval(5), - new NumberEval(10), - new NumberEval(10), - new NumberEval(25), - }; - - AreaEval ae = createAreaEval("A1:A5", values); - - AreaEval matchAE = createAreaEval("C1:C1", new ValueEval[] { MATCH_LARGEST_LTE, }); - - try { - confirmInt(4, invokeMatch(new NumberEval(10), ae, matchAE)); - } catch (RuntimeException e) { - if(e.getMessage().startsWith("Unexpected match_type type")) { - // identified bug 44421 - fail(e.getMessage()); - } - // some other error ?? - throw e; - } - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMathX.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMathX.java deleted file mode 100644 index eb576506a0..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMathX.java +++ /dev/null @@ -1,909 +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 23, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class TestMathX extends AbstractNumericTestCase { - - public void testAcosh() { - double d = 0; - - d = MathX.acosh(0); - assertTrue("Acosh 0 is NaN", Double.isNaN(d)); - - d = MathX.acosh(1); - assertEquals("Acosh 1 ", 0, d); - - d = MathX.acosh(-1); - assertTrue("Acosh -1 is NaN", Double.isNaN(d)); - - d = MathX.acosh(100); - assertEquals("Acosh 100 ", 5.298292366d, d); - - d = MathX.acosh(101.001); - assertEquals("Acosh 101.001 ", 5.308253091d, d); - - d = MathX.acosh(200000); - assertEquals("Acosh 200000 ", 12.89921983d, d); - - } - - public void testAsinh() { - double d = 0; - - d = MathX.asinh(0); - assertEquals("asinh 0", d, 0); - - d = MathX.asinh(1); - assertEquals("asinh 1 ", 0.881373587, d); - - d = MathX.asinh(-1); - assertEquals("asinh -1 ", -0.881373587, d); - - d = MathX.asinh(-100); - assertEquals("asinh -100 ", -5.298342366, d); - - d = MathX.asinh(100); - assertEquals("asinh 100 ", 5.298342366, d); - - d = MathX.asinh(200000); - assertEquals("asinh 200000", 12.899219826096400, d); - - d = MathX.asinh(-200000); - assertEquals("asinh -200000 ", -12.899223853137, d); - - } - - public void testAtanh() { - double d = 0; - d = MathX.atanh(0); - assertEquals("atanh 0", d, 0); - - d = MathX.atanh(1); - assertEquals("atanh 1 ", Double.POSITIVE_INFINITY, d); - - d = MathX.atanh(-1); - assertEquals("atanh -1 ", Double.NEGATIVE_INFINITY, d); - - d = MathX.atanh(-100); - assertEquals("atanh -100 ", Double.NaN, d); - - d = MathX.atanh(100); - assertEquals("atanh 100 ", Double.NaN, d); - - d = MathX.atanh(200000); - assertEquals("atanh 200000", Double.NaN, d); - - d = MathX.atanh(-200000); - assertEquals("atanh -200000 ", Double.NaN, d); - - d = MathX.atanh(0.1); - assertEquals("atanh 0.1", 0.100335348, d); - - d = MathX.atanh(-0.1); - assertEquals("atanh -0.1 ", -0.100335348, d); - - } - - public void testCosh() { - double d = 0; - d = MathX.cosh(0); - assertEquals("cosh 0", 1, d); - - d = MathX.cosh(1); - assertEquals("cosh 1 ", 1.543080635, d); - - d = MathX.cosh(-1); - assertEquals("cosh -1 ", 1.543080635, d); - - d = MathX.cosh(-100); - assertEquals("cosh -100 ", 1.344058570908070E+43, d); - - d = MathX.cosh(100); - assertEquals("cosh 100 ", 1.344058570908070E+43, d); - - d = MathX.cosh(15); - assertEquals("cosh 15", 1634508.686, d); - - d = MathX.cosh(-15); - assertEquals("cosh -15 ", 1634508.686, d); - - d = MathX.cosh(0.1); - assertEquals("cosh 0.1", 1.005004168, d); - - d = MathX.cosh(-0.1); - assertEquals("cosh -0.1 ", 1.005004168, d); - - } - - public void testTanh() { - double d = 0; - d = MathX.tanh(0); - assertEquals("tanh 0", 0, d); - - d = MathX.tanh(1); - assertEquals("tanh 1 ", 0.761594156, d); - - d = MathX.tanh(-1); - assertEquals("tanh -1 ", -0.761594156, d); - - d = MathX.tanh(-100); - assertEquals("tanh -100 ", -1, d); - - d = MathX.tanh(100); - assertEquals("tanh 100 ", 1, d); - - d = MathX.tanh(15); - assertEquals("tanh 15", 1, d); - - d = MathX.tanh(-15); - assertEquals("tanh -15 ", -1, d); - - d = MathX.tanh(0.1); - assertEquals("tanh 0.1", 0.099667995, d); - - d = MathX.tanh(-0.1); - assertEquals("tanh -0.1 ", -0.099667995, d); - - } - - public void testMax() { - double[] d = new double[100]; - d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; - d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; - d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; - d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; - d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; - - double m = MathX.max(d); - assertEquals("Max ", 20.1, m); - - d = new double[1000]; - m = MathX.max(d); - assertEquals("Max ", 0, m); - - d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; - d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; - d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; - d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; - d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; - m = MathX.max(d); - assertEquals("Max ", 20.1, m); - - d = new double[20]; - d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; - d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; - d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; - d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; - d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; - m = MathX.max(d); - assertEquals("Max ", -1.1, m); - - } - - public void testMin() { - double[] d = new double[100]; - d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; - d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; - d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; - d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; - d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; - - double m = MathX.min(d); - assertEquals("Min ", 0, m); - - d = new double[20]; - d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; - d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; - d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; - d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; - d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; - - m = MathX.min(d); - assertEquals("Min ", 1.1, m); - - d = new double[1000]; - m = MathX.min(d); - assertEquals("Min ", 0, m); - - d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; - d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; - d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; - d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; - d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; - m = MathX.min(d); - assertEquals("Min ", -19.1, m); - - d = new double[20]; - d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; - d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; - d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; - d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; - d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; - m = MathX.min(d); - assertEquals("Min ", -20.1, m); - } - - public void testProduct() { - double[] d = new double[100]; - d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; - d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; - d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; - d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; - d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; - - double m = MathX.min(d); - assertEquals("Min ", 0, m); - - d = new double[20]; - d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; - d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; - d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; - d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; - d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; - - m = MathX.min(d); - assertEquals("Min ", 1.1, m); - - d = new double[1000]; - m = MathX.min(d); - assertEquals("Min ", 0, m); - - d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; - d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; - d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; - d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; - d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; - m = MathX.min(d); - assertEquals("Min ", -19.1, m); - - d = new double[20]; - d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; - d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; - d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; - d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; - d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; - m = MathX.min(d); - assertEquals("Min ", -20.1, m); - } - - public void testMod() { - } - - public void testNChooseK() { - int n=100; - int k=50; - double d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 1.00891344545564E29, d); - - n = -1; k = 1; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", Double.NaN, d); - - n = 1; k = -1; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", Double.NaN, d); - - n = 0; k = 1; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", Double.NaN, d); - - n = 1; k = 0; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 1, d); - - n = 10; k = 9; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 10, d); - - n = 10; k = 10; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 1, d); - - n = 10; k = 1; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 10, d); - - n = 1000; k = 1; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 1000, d); // awesome ;) - - n = 1000; k = 2; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 499500, d); // awesome ;) - - n = 13; k = 7; - d = MathX.nChooseK(n, k); - assertEquals("NChooseK ", 1716, d); - - } - - public void testSign() { - final short minus = -1; - final short zero = 0; - final short plus = 1; - double d = 0; - - - assertEquals("Sign ", minus, MathX.sign(minus)); - assertEquals("Sign ", plus, MathX.sign(plus)); - assertEquals("Sign ", zero, MathX.sign(zero)); - - d = 0; - assertEquals("Sign ", zero, MathX.sign(d)); - - d = -1.000001; - assertEquals("Sign ", minus, MathX.sign(d)); - - d = -.000001; - assertEquals("Sign ", minus, MathX.sign(d)); - - d = -1E-200; - assertEquals("Sign ", minus, MathX.sign(d)); - - d = Double.NEGATIVE_INFINITY; - assertEquals("Sign ", minus, MathX.sign(d)); - - d = -200.11; - assertEquals("Sign ", minus, MathX.sign(d)); - - d = -2000000000000.11; - assertEquals("Sign ", minus, MathX.sign(d)); - - d = 1.000001; - assertEquals("Sign ", plus, MathX.sign(d)); - - d = .000001; - assertEquals("Sign ", plus, MathX.sign(d)); - - d = 1E-200; - assertEquals("Sign ", plus, MathX.sign(d)); - - d = Double.POSITIVE_INFINITY; - assertEquals("Sign ", plus, MathX.sign(d)); - - d = 200.11; - assertEquals("Sign ", plus, MathX.sign(d)); - - d = 2000000000000.11; - assertEquals("Sign ", plus, MathX.sign(d)); - - } - - public void testSinh() { - double d = 0; - d = MathX.sinh(0); - assertEquals("sinh 0", 0, d); - - d = MathX.sinh(1); - assertEquals("sinh 1 ", 1.175201194, d); - - d = MathX.sinh(-1); - assertEquals("sinh -1 ", -1.175201194, d); - - d = MathX.sinh(-100); - assertEquals("sinh -100 ", -1.344058570908070E+43, d); - - d = MathX.sinh(100); - assertEquals("sinh 100 ", 1.344058570908070E+43, d); - - d = MathX.sinh(15); - assertEquals("sinh 15", 1634508.686, d); - - d = MathX.sinh(-15); - assertEquals("sinh -15 ", -1634508.686, d); - - d = MathX.sinh(0.1); - assertEquals("sinh 0.1", 0.10016675, d); - - d = MathX.sinh(-0.1); - assertEquals("sinh -0.1 ", -0.10016675, d); - - } - - public void testSum() { - double[] d = new double[100]; - d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; - d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; - d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; - d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; - d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; - - double s = MathX.sum(d); - assertEquals("Sum ", 212, s); - - d = new double[1000]; - s = MathX.sum(d); - assertEquals("Sum ", 0, s); - - d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; - d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; - d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; - d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; - d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; - s = MathX.sum(d); - assertEquals("Sum ", 10, s); - - d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; - d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; - d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; - d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; - d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; - s = MathX.sum(d); - assertEquals("Sum ", -212, s); - - } - - public void testSumproduct() { - double d = 0; - double[][] darr = new double[][] - {{0 ,0.11 ,23.23}, - {1 ,0.22 ,46.46}, - {2 ,0.33 ,69.69}, - {3 ,0.44 ,92.92}, - {4 ,0.55 ,116.15}, - {5 ,0.66 ,139.38}, - {6 ,0.77 ,162.61}, - {7 ,0.88 ,185.84}, - {8 ,0.99 ,209.07}, - {9 ,1.1 ,232.3}, - {10 ,1.21 ,255.53}}; - d = MathX.sumproduct(darr); - assertEquals("Sumproduct ", 4.243234425E+22, d); - darr = new double[][] - {{0 ,0.11 ,23.23}, - {0 ,0.22 ,46.46}, - {0 ,0.33 ,69.69}, - {0 ,0.44 ,92.92}, - {0 ,0.55 ,116.15}, - {0 ,0.66 ,139.38}, - {0 ,0.77 ,162.61}, - {0 ,0.88 ,185.84}, - {0 ,0.99 ,209.07}, - {0 ,1.1 ,232.3}, - {0 ,1.21 ,255.53}}; - d = MathX.sumproduct(darr); - assertEquals("Sumproduct ", 4.243234425E+22, d); - - darr = new double[][] - {{0, 0, 0, 0, 0, 0, 0, 0}, - {0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88}, - {23.23, 46.46, 69.69, 92.92, 116.15, 139.38, 162.61, 185.84}}; - d = MathX.sumproduct(darr); - assertEquals("Sumproduct ", 0, d); - - darr = new double[][] - {{0, 1, 2, 3, 4, 5, 6, 7}, - {0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88}, - {23.23, 46.46, 69.69, 92.92, 116.15, 139.38, 162.61, 185.84}}; - d = MathX.sumproduct(darr); - assertEquals("Sumproduct ", 2790.3876, d); - - - } - - public void testSumsq() { - double[] d = new double[100]; - d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; - d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; - d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; - d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; - d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; - - double s = MathX.sumsq(d); - assertEquals("Sumsq ", 2912.2, s); - - d = new double[1000]; - s = MathX.sumsq(d); - assertEquals("Sumsq ", 0, s); - - d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; - d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; - d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; - d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; - d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; - s = MathX.sumsq(d); - assertEquals("Sumsq ", 2912.2, s); - - d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; - d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; - d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; - d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; - d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; - s = MathX.sumsq(d); - assertEquals("Sumsq ", 2912.2, s); - } - - public void testFactorial() { - int n = 0; - double s = 0; - - n = 0; - s = MathX.factorial(n); - assertEquals("Factorial ", 1, s); - - n = 1; - s = MathX.factorial(n); - assertEquals("Factorial ", 1, s); - - n = 10; - s = MathX.factorial(n); - assertEquals("Factorial ", 3628800, s); - - n = 99; - s = MathX.factorial(n); - assertEquals("Factorial ", 9.33262154439E+155, s); - - n = -1; - s = MathX.factorial(n); - assertEquals("Factorial ", Double.NaN, s); - - n = Integer.MAX_VALUE; - s = MathX.factorial(n); - assertEquals("Factorial ", Double.POSITIVE_INFINITY, s); - } - - public void testSumx2my2() { - double d = 0; - double[] xarr = null; - double[] yarr = null; - - xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - d = MathX.sumx2my2(xarr, yarr); - assertEquals("sumx2my2 ", 100, d); - - xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}; - yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - d = MathX.sumx2my2(xarr, yarr); - assertEquals("sumx2my2 ", 100, d); - - xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - d = MathX.sumx2my2(xarr, yarr); - assertEquals("sumx2my2 ", -100, d); - - xarr = new double[]{10}; - yarr = new double[]{9}; - d = MathX.sumx2my2(xarr, yarr); - assertEquals("sumx2my2 ", 19, d); - - xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - d = MathX.sumx2my2(xarr, yarr); - assertEquals("sumx2my2 ", 0, d); - - } - - public void testSumx2py2() { - double d = 0; - double[] xarr = null; - double[] yarr = null; - - xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - d = MathX.sumx2py2(xarr, yarr); - assertEquals("sumx2py2 ", 670, d); - - xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}; - yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - d = MathX.sumx2py2(xarr, yarr); - assertEquals("sumx2py2 ", 670, d); - - xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - d = MathX.sumx2py2(xarr, yarr); - assertEquals("sumx2py2 ", 670, d); - - xarr = new double[]{10}; - yarr = new double[]{9}; - d = MathX.sumx2py2(xarr, yarr); - assertEquals("sumx2py2 ", 181, d); - - xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - d = MathX.sumx2py2(xarr, yarr); - assertEquals("sumx2py2 ", 770, d); - } - - public void testSumxmy2() { - double d = 0; - double[] xarr = null; - double[] yarr = null; - - xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - d = MathX.sumxmy2(xarr, yarr); - assertEquals("sumxmy2 ", 10, d); - - xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}; - yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - d = MathX.sumxmy2(xarr, yarr); - assertEquals("sumxmy2 ", 1330, d); - - xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - d = MathX.sumxmy2(xarr, yarr); - assertEquals("sumxmy2 ", 10, d); - - xarr = new double[]{10}; - yarr = new double[]{9}; - d = MathX.sumxmy2(xarr, yarr); - assertEquals("sumxmy2 ", 1, d); - - xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - d = MathX.sumxmy2(xarr, yarr); - assertEquals("sumxmy2 ", 0, d); - } - - public void testRound() { - double d = 0; - int p = 0; - - d = 0; p = 0; - assertEquals("round ", 0, MathX.round(d, p)); - - d = 10; p = 0; - assertEquals("round ", 10, MathX.round(d, p)); - - d = 123.23; p = 0; - assertEquals("round ", 123, MathX.round(d, p)); - - d = -123.23; p = 0; - assertEquals("round ", -123, MathX.round(d, p)); - - d = 123.12; p = 2; - assertEquals("round ", 123.12, MathX.round(d, p)); - - d = 88.123459; p = 5; - assertEquals("round ", 88.12346, MathX.round(d, p)); - - d = 0; p = 2; - assertEquals("round ", 0, MathX.round(d, p)); - - d = 0; p = -1; - assertEquals("round ", 0, MathX.round(d, p)); - - d = 0.01; p = -1; - assertEquals("round ", 0, MathX.round(d, p)); - - d = 123.12; p = -2; - assertEquals("round ", 100, MathX.round(d, p)); - - d = 88.123459; p = -3; - assertEquals("round ", 0, MathX.round(d, p)); - - d = 49.00000001; p = -1; - assertEquals("round ", 50, MathX.round(d, p)); - - d = 149.999999; p = -2; - assertEquals("round ", 100, MathX.round(d, p)); - - d = 150.0; p = -2; - assertEquals("round ", 200, MathX.round(d, p)); - } - - public void testRoundDown() { - double d = 0; - int p = 0; - - d = 0; p = 0; - assertEquals("roundDown ", 0, MathX.roundDown(d, p)); - - d = 10; p = 0; - assertEquals("roundDown ", 10, MathX.roundDown(d, p)); - - d = 123.99; p = 0; - assertEquals("roundDown ", 123, MathX.roundDown(d, p)); - - d = -123.99; p = 0; - assertEquals("roundDown ", -123, MathX.roundDown(d, p)); - - d = 123.99; p = 2; - assertEquals("roundDown ", 123.99, MathX.roundDown(d, p)); - - d = 88.123459; p = 5; - assertEquals("roundDown ", 88.12345, MathX.roundDown(d, p)); - - d = 0; p = 2; - assertEquals("roundDown ", 0, MathX.roundDown(d, p)); - - d = 0; p = -1; - assertEquals("roundDown ", 0, MathX.roundDown(d, p)); - - d = 0.01; p = -1; - assertEquals("roundDown ", 0, MathX.roundDown(d, p)); - - d = 199.12; p = -2; - assertEquals("roundDown ", 100, MathX.roundDown(d, p)); - - d = 88.123459; p = -3; - assertEquals("roundDown ", 0, MathX.roundDown(d, p)); - - d = 99.00000001; p = -1; - assertEquals("roundDown ", 90, MathX.roundDown(d, p)); - - d = 100.00001; p = -2; - assertEquals("roundDown ", 100, MathX.roundDown(d, p)); - - d = 150.0; p = -2; - assertEquals("roundDown ", 100, MathX.roundDown(d, p)); - } - - public void testRoundUp() { - double d = 0; - int p = 0; - - d = 0; p = 0; - assertEquals("roundUp ", 0, MathX.roundUp(d, p)); - - d = 10; p = 0; - assertEquals("roundUp ", 10, MathX.roundUp(d, p)); - - d = 123.23; p = 0; - assertEquals("roundUp ", 124, MathX.roundUp(d, p)); - - d = -123.23; p = 0; - assertEquals("roundUp ", -124, MathX.roundUp(d, p)); - - d = 123.12; p = 2; - assertEquals("roundUp ", 123.12, MathX.roundUp(d, p)); - - d = 88.123459; p = 5; - assertEquals("roundUp ", 88.12346, MathX.roundUp(d, p)); - - d = 0; p = 2; - assertEquals("roundUp ", 0, MathX.roundUp(d, p)); - - d = 0; p = -1; - assertEquals("roundUp ", 0, MathX.roundUp(d, p)); - - d = 0.01; p = -1; - assertEquals("roundUp ", 10, MathX.roundUp(d, p)); - - d = 123.12; p = -2; - assertEquals("roundUp ", 200, MathX.roundUp(d, p)); - - d = 88.123459; p = -3; - assertEquals("roundUp ", 1000, MathX.roundUp(d, p)); - - d = 49.00000001; p = -1; - assertEquals("roundUp ", 50, MathX.roundUp(d, p)); - - d = 149.999999; p = -2; - assertEquals("roundUp ", 200, MathX.roundUp(d, p)); - - d = 150.0; p = -2; - assertEquals("roundUp ", 200, MathX.roundUp(d, p)); - } - - public void testCeiling() { - double d = 0; - double s = 0; - - d = 0; s = 0; - assertEquals("ceiling ", 0, MathX.ceiling(d, s)); - - d = 1; s = 0; - assertEquals("ceiling ", 0, MathX.ceiling(d, s)); - - d = 0; s = 1; - assertEquals("ceiling ", 0, MathX.ceiling(d, s)); - - d = -1; s = 0; - assertEquals("ceiling ", 0, MathX.ceiling(d, s)); - - d = 0; s = -1; - assertEquals("ceiling ", 0, MathX.ceiling(d, s)); - - d = 10; s = 1.11; - assertEquals("ceiling ", 11.1, MathX.ceiling(d, s)); - - d = 11.12333; s = 0.03499; - assertEquals("ceiling ", 11.12682, MathX.ceiling(d, s)); - - d = -11.12333; s = 0.03499; - assertEquals("ceiling ", Double.NaN, MathX.ceiling(d, s)); - - d = 11.12333; s = -0.03499; - assertEquals("ceiling ", Double.NaN, MathX.ceiling(d, s)); - - d = -11.12333; s = -0.03499; - assertEquals("ceiling ", -11.12682, MathX.ceiling(d, s)); - - d = 100; s = 0.001; - assertEquals("ceiling ", 100, MathX.ceiling(d, s)); - - d = -0.001; s = -9.99; - assertEquals("ceiling ", -9.99, MathX.ceiling(d, s)); - - d = 4.42; s = 0.05; - assertEquals("ceiling ", 4.45, MathX.ceiling(d, s)); - - d = 0.05; s = 4.42; - assertEquals("ceiling ", 4.42, MathX.ceiling(d, s)); - - d = 0.6666; s = 3.33; - assertEquals("ceiling ", 3.33, MathX.ceiling(d, s)); - - d = 2d/3; s = 3.33; - assertEquals("ceiling ", 3.33, MathX.ceiling(d, s)); - } - - public void testFloor() { - double d = 0; - double s = 0; - - d = 0; s = 0; - assertEquals("floor ", 0, MathX.floor(d, s)); - - d = 1; s = 0; - assertEquals("floor ", Double.NaN, MathX.floor(d, s)); - - d = 0; s = 1; - assertEquals("floor ", 0, MathX.floor(d, s)); - - d = -1; s = 0; - assertEquals("floor ", Double.NaN, MathX.floor(d, s)); - - d = 0; s = -1; - assertEquals("floor ", 0, MathX.floor(d, s)); - - d = 10; s = 1.11; - assertEquals("floor ", 9.99, MathX.floor(d, s)); - - d = 11.12333; s = 0.03499; - assertEquals("floor ", 11.09183, MathX.floor(d, s)); - - d = -11.12333; s = 0.03499; - assertEquals("floor ", Double.NaN, MathX.floor(d, s)); - - d = 11.12333; s = -0.03499; - assertEquals("floor ", Double.NaN, MathX.floor(d, s)); - - d = -11.12333; s = -0.03499; - assertEquals("floor ", -11.09183, MathX.floor(d, s)); - - d = 100; s = 0.001; - assertEquals("floor ", 100, MathX.floor(d, s)); - - d = -0.001; s = -9.99; - assertEquals("floor ", 0, MathX.floor(d, s)); - - d = 4.42; s = 0.05; - assertEquals("floor ", 4.4, MathX.floor(d, s)); - - d = 0.05; s = 4.42; - assertEquals("floor ", 0, MathX.floor(d, s)); - - d = 0.6666; s = 3.33; - assertEquals("floor ", 0, MathX.floor(d, s)); - - d = 2d/3; s = 3.33; - assertEquals("floor ", 0, MathX.floor(d, s)); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java deleted file mode 100755 index dc3d595aed..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java +++ /dev/null @@ -1,115 +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.AreaPtg; -import org.apache.poi.hssf.record.formula.ReferencePtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.Ref2DEval; -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; - -import junit.framework.TestCase; -/** - * Tests for Excel function MID() - * - * @author Josh Micich - */ -public final class TestMid extends TestCase { - - - private static Eval invokeMid(Eval text, Eval startPos, Eval numChars) { - Eval[] args = new Eval[] { text, startPos, numChars, }; - return new Mid().evaluate(args, -1, (short)-1); - } - - private void confirmMid(Eval text, Eval startPos, Eval numChars, String expected) { - Eval result = invokeMid(text, startPos, numChars); - assertEquals(StringEval.class, result.getClass()); - assertEquals(expected, ((StringEval)result).getStringValue()); - } - - private void confirmMid(Eval text, Eval startPos, Eval numChars, ErrorEval expectedError) { - Eval result = invokeMid(text, startPos, numChars); - assertEquals(ErrorEval.class, result.getClass()); - assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); - } - - public void testBasic() { - - confirmMid(new StringEval("galactic"), new NumberEval(3), new NumberEval(4), "lact"); - } - - /** - * Valid cases where args are not precisely (string, int, int) but can be resolved OK. - */ - public void testUnusualArgs() { - // startPos with fractional digits - confirmMid(new StringEval("galactic"), new NumberEval(3.1), new NumberEval(4), "lact"); - - // string startPos - confirmMid(new StringEval("galactic"), new StringEval("3"), new NumberEval(4), "lact"); - - // text (first) arg type is number, other args are strings with fractional digits - confirmMid(new NumberEval(123456), new StringEval("3.1"), new StringEval("2.9"), "34"); - - // startPos is 1x1 area ref, numChars is cell ref - AreaEval aeStart = new Area2DEval(new AreaPtg("A1:A1"), new ValueEval[] { new NumberEval(2), } ); - RefEval reNumChars = new Ref2DEval(new ReferencePtg("B1"), new NumberEval(3)); - confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala"); - - confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, ""); - - confirmMid(new StringEval("galactic"), new NumberEval(3), BoolEval.FALSE, ""); - confirmMid(new StringEval("galactic"), new NumberEval(3), BoolEval.TRUE, "l"); - confirmMid(BlankEval.INSTANCE, new NumberEval(3), BoolEval.TRUE, ""); - - } - - /** - * Extreme values for startPos and numChars - */ - public void testExtremes() { - confirmMid(new StringEval("galactic"), new NumberEval(4), new NumberEval(400), "actic"); - - confirmMid(new StringEval("galactic"), new NumberEval(30), new NumberEval(4), ""); - confirmMid(new StringEval("galactic"), new NumberEval(3), new NumberEval(0), ""); - } - - /** - * All sorts of ways to make MID return defined errors. - */ - public void testErrors() { - confirmMid(ErrorEval.NAME_INVALID, new NumberEval(3), new NumberEval(4), ErrorEval.NAME_INVALID); - confirmMid(new StringEval("galactic"), ErrorEval.NAME_INVALID, new NumberEval(4), ErrorEval.NAME_INVALID); - confirmMid(new StringEval("galactic"), new NumberEval(3), ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); - confirmMid(new StringEval("galactic"), ErrorEval.DIV_ZERO, ErrorEval.NAME_INVALID, ErrorEval.DIV_ZERO); - - confirmMid(new StringEval("galactic"), BlankEval.INSTANCE, new NumberEval(3.1), ErrorEval.VALUE_INVALID); - - confirmMid(new StringEval("galactic"), new NumberEval(0), new NumberEval(4), ErrorEval.VALUE_INVALID); - confirmMid(new StringEval("galactic"), new NumberEval(1), new NumberEval(-1), ErrorEval.VALUE_INVALID); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java deleted file mode 100755 index f114662985..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.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.functions; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.functions.Offset.LinearOffsetRange; - -/** - * Tests for OFFSET function implementation - * - * @author Josh Micich - */ -public final class TestOffset extends TestCase { - - - private static void confirmDoubleConvert(double doubleVal, int expected) { - assertEquals(expected, Offset.convertDoubleToInt(doubleVal)); - } - /** - * Excel's double to int conversion (for function 'OFFSET()') behaves more like Math.floor(). - * Note - negative values are not symmetrical - */ - public void testDoubleConversion() { - - confirmDoubleConvert(100.09, 100); - confirmDoubleConvert(100.01, 100); - confirmDoubleConvert(100.00, 100); - confirmDoubleConvert(99.99, 99); - - confirmDoubleConvert(+2.01, +2); - confirmDoubleConvert(+2.00, +2); - confirmDoubleConvert(+1.99, +1); - confirmDoubleConvert(+1.01, +1); - confirmDoubleConvert(+1.00, +1); - confirmDoubleConvert(+0.99, 0); - confirmDoubleConvert(+0.01, 0); - confirmDoubleConvert( 0.00, 0); - confirmDoubleConvert(-0.01, -1); - confirmDoubleConvert(-0.99, -1); - confirmDoubleConvert(-1.00, -1); - confirmDoubleConvert(-1.01, -2); - confirmDoubleConvert(-1.99, -2); - confirmDoubleConvert(-2.00, -2); - confirmDoubleConvert(-2.01, -3); - } - - public void testLinearOffsetRange() { - LinearOffsetRange lor; - - lor = new LinearOffsetRange(3, 2); - assertEquals(3, lor.getFirstIndex()); - assertEquals(4, lor.getLastIndex()); - lor = lor.normaliseAndTranslate(0); // expected no change - assertEquals(3, lor.getFirstIndex()); - assertEquals(4, lor.getLastIndex()); - - lor = lor.normaliseAndTranslate(5); - assertEquals(8, lor.getFirstIndex()); - assertEquals(9, lor.getLastIndex()); - - // negative length - - lor = new LinearOffsetRange(6, -4).normaliseAndTranslate(0); - assertEquals(3, lor.getFirstIndex()); - assertEquals(6, lor.getLastIndex()); - - - // bounds checking - lor = new LinearOffsetRange(0, 100); - assertFalse(lor.isOutOfBounds(0, 16383)); - lor = lor.normaliseAndTranslate(16300); - assertTrue(lor.isOutOfBounds(0, 16383)); - assertFalse(lor.isOutOfBounds(0, 65535)); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestPmt.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestPmt.java deleted file mode 100644 index 935615acae..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestPmt.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.functions; - -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.usermodel.HSSFErrorConstants; - -/** - * - * @author Josh Micich - */ -public final class TestPmt extends TestCase { - - private static void confirm(double expected, NumberEval ne) { - // only asserting accuracy to 4 fractional digits - assertEquals(expected, ne.getNumberValue(), 0.00005); - } - private static Eval invoke(Eval[] args) { - return new Pmt().evaluate(args, -1, (short)-1); - } - /** - * Invocation when not expecting an error result - */ - private static NumberEval invokeNormal(Eval[] args) { - Eval ev = invoke(args); - if(ev instanceof ErrorEval) { - throw new AssertionFailedError("Normal evaluation failed with error code: " - + ev.toString()); - } - return (NumberEval) ev; - } - - private static void confirm(double expected, double rate, double nper, double pv, double fv, boolean isBeginning) { - Eval[] args = { - new NumberEval(rate), - new NumberEval(nper), - new NumberEval(pv), - new NumberEval(fv), - new NumberEval(isBeginning ? 1 : 0), - }; - confirm(expected, invokeNormal(args)); - } - - - public void testBasic() { - confirm(-1037.0321, (0.08/12), 10, 10000, 0, false); - confirm(-1030.1643, (0.08/12), 10, 10000, 0, true); - } - - public void test3args() { - - Eval[] args = { - new NumberEval(0.005), - new NumberEval(24), - new NumberEval(1000), - }; - Eval ev = invoke(args); - if(ev instanceof ErrorEval) { - ErrorEval err = (ErrorEval) ev; - if(err.getErrorCode() == HSSFErrorConstants.ERROR_VALUE) { - throw new AssertionFailedError("Identified bug 44691"); - } - } - - confirm(-44.3206, invokeNormal(args)); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestRoundFuncs.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestRoundFuncs.java deleted file mode 100755 index a6ce345aeb..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestRoundFuncs.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.functions; - -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; - -import junit.framework.TestCase; - -/** - * Test cases for ROUND(), ROUNDUP(), ROUNDDOWN() - * - * @author Josh Micich - */ -public final class TestRoundFuncs extends TestCase { - public void testRounddownWithStringArg() { - - Eval strArg = new StringEval("abc"); - Eval[] args = { strArg, new NumberEval(2), }; - Eval result = new Rounddown().evaluate(args, -1, (short)-1); - assertEquals(ErrorEval.VALUE_INVALID, result); - } - - public void testRoundupWithStringArg() { - - Eval strArg = new StringEval("abc"); - Eval[] args = { strArg, new NumberEval(2), }; - Eval result = new Roundup().evaluate(args, -1, (short)-1); - assertEquals(ErrorEval.VALUE_INVALID, result); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestRowCol.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestRowCol.java deleted file mode 100755 index 4002c30d0f..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestRowCol.java +++ /dev/null @@ -1,102 +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 junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.eval.Eval; - -/** - * Tests for ROW(), ROWS(), COLUMN(), COLUMNS() - * - * @author Josh Micich - */ -public final class TestRowCol extends TestCase { - - public TestRowCol(String testName) { - super(testName); - } - - public void testCol() { - Function target = new Column(); - { - Eval[] args = { EvalFactory.createRefEval("C5"), }; - double actual = NumericFunctionInvoker.invoke(target, args); - assertEquals(3, actual, 0D); - } - { - Eval[] args = { EvalFactory.createAreaEval("E2:H12", 4, 11), }; - double actual = NumericFunctionInvoker.invoke(target, args); - assertEquals(5, actual, 0D); - } - } - - public void testRow() { - Function target = new Row(); - { - Eval[] args = { EvalFactory.createRefEval("C5"), }; - double actual = NumericFunctionInvoker.invoke(target, args); - assertEquals(5, actual, 0D); - } - { - Eval[] args = { EvalFactory.createAreaEval("E2:H12", 4, 11), }; - double actual = NumericFunctionInvoker.invoke(target, args); - assertEquals(2, actual, 0D); - } - } - - public void testColumns() { - - confirmColumnsFunc("A1:F1", 6, 1); - confirmColumnsFunc("A1:C2", 3, 2); - confirmColumnsFunc("A1:B3", 2, 3); - confirmColumnsFunc("A1:A6", 1, 6); - - Eval[] args = { EvalFactory.createRefEval("C5"), }; - double actual = NumericFunctionInvoker.invoke(new Columns(), args); - assertEquals(1, actual, 0D); - } - - public void testRows() { - - confirmRowsFunc("A1:F1", 6, 1); - confirmRowsFunc("A1:C2", 3, 2); - confirmRowsFunc("A1:B3", 2, 3); - confirmRowsFunc("A1:A6", 1, 6); - - Eval[] args = { EvalFactory.createRefEval("C5"), }; - double actual = NumericFunctionInvoker.invoke(new Rows(), args); - assertEquals(1, actual, 0D); - } - - private static void confirmRowsFunc(String areaRefStr, int nCols, int nRows) { - Eval[] args = { EvalFactory.createAreaEval(areaRefStr, nCols, nRows), }; - - double actual = NumericFunctionInvoker.invoke(new Rows(), args); - assertEquals(nRows, actual, 0D); - } - - - private static void confirmColumnsFunc(String areaRefStr, int nCols, int nRows) { - Eval[] args = { EvalFactory.createAreaEval(areaRefStr, nCols, nRows), }; - - double actual = NumericFunctionInvoker.invoke(new Columns(), args); - assertEquals(nCols, actual, 0D); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestStatsLib.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestStatsLib.java deleted file mode 100644 index 237366baf0..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestStatsLib.java +++ /dev/null @@ -1,262 +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 30, 2005 - * - */ -package org.apache.poi.hssf.record.formula.functions; - - -/** - * @author Amol S. Deshmukh < amolweb at ya hoo dot com > - * - */ -public class TestStatsLib extends AbstractNumericTestCase { - - public void testDevsq() { - double[] v = null; - double d, x = 0; - - v = new double[] {1,2,3,4,5,6,7,8,9,10}; - d = StatsLib.devsq(v); - x = 82.5; - assertEquals("devsq ", x, d); - - v = new double[] {1,1,1,1,1,1,1,1,1,1}; - d = StatsLib.devsq(v); - x = 0; - assertEquals("devsq ", x, d); - - v = new double[] {0,0,0,0,0,0,0,0,0,0}; - d = StatsLib.devsq(v); - x = 0; - assertEquals("devsq ", x, d); - - v = new double[] {1,2,1,2,1,2,1,2,1,2}; - d = StatsLib.devsq(v); - x = 2.5; - assertEquals("devsq ", x, d); - - v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; - d = StatsLib.devsq(v); - x = 10953.7416965767; - assertEquals("devsq ", x, d); - - v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; - d = StatsLib.devsq(v); - x = 82.5; - assertEquals("devsq ", x, d); - } - - public void testKthLargest() { - double[] v = null; - double d, x = 0; - - v = new double[] {1,2,3,4,5,6,7,8,9,10}; - d = StatsLib.kthLargest(v, 3); - x = 8; - assertEquals("kthLargest ", x, d); - - v = new double[] {1,1,1,1,1,1,1,1,1,1}; - d = StatsLib.kthLargest(v, 3); - x = 1; - assertEquals("kthLargest ", x, d); - - v = new double[] {0,0,0,0,0,0,0,0,0,0}; - d = StatsLib.kthLargest(v, 3); - x = 0; - assertEquals("kthLargest ", x, d); - - v = new double[] {1,2,1,2,1,2,1,2,1,2}; - d = StatsLib.kthLargest(v, 3); - x = 2; - assertEquals("kthLargest ", x, d); - - v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; - d = StatsLib.kthLargest(v, 3); - x = 5.37828; - assertEquals("kthLargest ", x, d); - - v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; - d = StatsLib.kthLargest(v, 3); - x = -3; - assertEquals("kthLargest ", x, d); - } - - public void testKthSmallest() { - } - - public void testAvedev() { - double[] v = null; - double d, x = 0; - - v = new double[] {1,2,3,4,5,6,7,8,9,10}; - d = StatsLib.avedev(v); - x = 2.5; - assertEquals("avedev ", x, d); - - v = new double[] {1,1,1,1,1,1,1,1,1,1}; - d = StatsLib.avedev(v); - x = 0; - assertEquals("avedev ", x, d); - - v = new double[] {0,0,0,0,0,0,0,0,0,0}; - d = StatsLib.avedev(v); - x = 0; - assertEquals("avedev ", x, d); - - v = new double[] {1,2,1,2,1,2,1,2,1,2}; - d = StatsLib.avedev(v); - x = 0.5; - assertEquals("avedev ", x, d); - - v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; - d = StatsLib.avedev(v); - x = 36.42176053333; - assertEquals("avedev ", x, d); - - v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; - d = StatsLib.avedev(v); - x = 2.5; - assertEquals("avedev ", x, d); - } - - public void testMedian() { - double[] v = null; - double d, x = 0; - - v = new double[] {1,2,3,4,5,6,7,8,9,10}; - d = StatsLib.median(v); - x = 5.5; - assertEquals("median ", x, d); - - v = new double[] {1,1,1,1,1,1,1,1,1,1}; - d = StatsLib.median(v); - x = 1; - assertEquals("median ", x, d); - - v = new double[] {0,0,0,0,0,0,0,0,0,0}; - d = StatsLib.median(v); - x = 0; - assertEquals("median ", x, d); - - v = new double[] {1,2,1,2,1,2,1,2,1,2}; - d = StatsLib.median(v); - x = 1.5; - assertEquals("median ", x, d); - - v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; - d = StatsLib.median(v); - x = 5.37828; - assertEquals("median ", x, d); - - v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; - d = StatsLib.median(v); - x = -5.5; - assertEquals("median ", x, d); - - v = new double[] {-2,-3,-4,-5,-6,-7,-8,-9,-10}; - d = StatsLib.median(v); - x = -6; - assertEquals("median ", x, d); - - v = new double[] {1,2,3,4,5,6,7,8,9}; - d = StatsLib.median(v); - x = 5; - assertEquals("median ", x, d); - } - - public void testMode() { - double[] v = null; - double d, x = 0; - - v = new double[] {1,2,3,4,5,6,7,8,9,10}; - d = StatsLib.mode(v); - x = Double.NaN; - assertEquals("mode ", x, d); - - v = new double[] {1,1,1,1,1,1,1,1,1,1}; - d = StatsLib.mode(v); - x = 1; - assertEquals("mode ", x, d); - - v = new double[] {0,0,0,0,0,0,0,0,0,0}; - d = StatsLib.mode(v); - x = 0; - assertEquals("mode ", x, d); - - v = new double[] {1,2,1,2,1,2,1,2,1,2}; - d = StatsLib.mode(v); - x = 1; - assertEquals("mode ", x, d); - - v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; - d = StatsLib.mode(v); - x = Double.NaN; - assertEquals("mode ", x, d); - - v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; - d = StatsLib.mode(v); - x = Double.NaN; - assertEquals("mode ", x, d); - - v = new double[] {1,2,3,4,1,1,1,1,0,0,0,0,0}; - d = StatsLib.mode(v); - x = 1; - assertEquals("mode ", x, d); - - v = new double[] {0,1,2,3,4,1,1,1,0,0,0,0,1}; - d = StatsLib.mode(v); - x = 0; - assertEquals("mode ", x, d); - } - - public void testStddev() { - double[] v = null; - double d, x = 0; - - v = new double[] {1,2,3,4,5,6,7,8,9,10}; - d = StatsLib.stdev(v); - x = 3.02765035410; - assertEquals("stdev ", x, d); - - v = new double[] {1,1,1,1,1,1,1,1,1,1}; - d = StatsLib.stdev(v); - x = 0; - assertEquals("stdev ", x, d); - - v = new double[] {0,0,0,0,0,0,0,0,0,0}; - d = StatsLib.stdev(v); - x = 0; - assertEquals("stdev ", x, d); - - v = new double[] {1,2,1,2,1,2,1,2,1,2}; - d = StatsLib.stdev(v); - x = 0.52704627669; - assertEquals("stdev ", x, d); - - v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; - d = StatsLib.stdev(v); - x = 52.33006233652; - assertEquals("stdev ", x, d); - - v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; - d = StatsLib.stdev(v); - x = 3.02765035410; - assertEquals("stdev ", x, d); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java deleted file mode 100755 index 73043911f4..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java +++ /dev/null @@ -1,120 +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.ReferencePtg; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.NumericValueEval; -import org.apache.poi.hssf.record.formula.eval.Ref2DEval; -import org.apache.poi.hssf.record.formula.eval.RefEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -import junit.framework.TestCase; - -/** - * Test cases for SUMPRODUCT() - * - * @author Josh Micich - */ -public final class TestSumproduct extends TestCase { - - private static Eval invokeSumproduct(Eval[] args) { - // srcCellRow and srcCellColumn are ignored by SUMPRODUCT - return new Sumproduct().evaluate(args, -1, (short)-1); - } - private static void confirmDouble(double expected, Eval actualEval) { - if(!(actualEval instanceof NumericValueEval)) { - fail("Expected numeric result"); - } - NumericValueEval nve = (NumericValueEval)actualEval; - assertEquals(expected, nve.getNumberValue(), 0); - } - - public void testScalarSimple() { - - RefEval refEval = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(3)); - Eval[] args = { - refEval, - new NumberEval(2), - }; - Eval result = invokeSumproduct(args); - confirmDouble(6D, result); - } - - - public void testAreaSimple() { - - AreaEval aeA = EvalFactory.createAreaEval("A1:A3", 1, 3); - AreaEval aeB = EvalFactory.createAreaEval("B1:B3", 1, 3); - ValueEval[] aValues = aeA.getValues(); - ValueEval[] bValues = aeB.getValues(); - aValues[0] = new NumberEval(2); - aValues[1] = new NumberEval(4); - aValues[2] = new NumberEval(5); - bValues[0] = new NumberEval(3); - bValues[1] = new NumberEval(6); - bValues[2] = new NumberEval(7); - - Eval[] args = { aeA, aeB, }; - Eval result = invokeSumproduct(args); - confirmDouble(65D, result); - } - - /** - * For scalar products, the terms may be 1x1 area refs - */ - public void testOneByOneArea() { - - AreaEval ae = EvalFactory.createAreaEval("A1:A1", 1, 1); - ae.getValues()[0] = new NumberEval(7); - - Eval[] args = { - ae, - new NumberEval(2), - }; - Eval result = invokeSumproduct(args); - confirmDouble(14D, result); - } - - - public void testMismatchAreaDimensions() { - - AreaEval aeA = EvalFactory.createAreaEval("A1:A3", 1, 3); - AreaEval aeB = EvalFactory.createAreaEval("B1:D1", 3, 1); - - Eval[] args; - args = new Eval[] { aeA, aeB, }; - assertEquals(ErrorEval.VALUE_INVALID, invokeSumproduct(args)); - - args = new Eval[] { aeA, new NumberEval(5), }; - assertEquals(ErrorEval.VALUE_INVALID, invokeSumproduct(args)); - } - - public void testAreaWithErrorCell() { - AreaEval aeA = EvalFactory.createAreaEval("A1:A2", 1, 2); - AreaEval aeB = EvalFactory.createAreaEval("B1:B2", 1, 2); - aeB.getValues()[1] = ErrorEval.REF_INVALID; - - Eval[] args = { aeA, aeB, }; - assertEquals(ErrorEval.REF_INVALID, invokeSumproduct(args)); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java deleted file mode 100755 index 4d63cad1c5..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java +++ /dev/null @@ -1,118 +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.ReferencePtg; -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.Ref2DEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; - -import junit.framework.TestCase; - -/** - * Test cases for Excel function T() - * - * @author Josh Micich - */ -public final class TestTFunc extends TestCase { - - /** - * @return the result of calling function T() with the specified argument - */ - private static Eval invokeT(Eval arg) { - Eval[] args = { arg, }; - Eval result = new T().evaluate(args, -1, (short)-1); - assertNotNull("result may never be null", result); - return result; - } - /** - * Simulates call: T(A1) - * where cell A1 has the specified innerValue - */ - private Eval invokeTWithReference(ValueEval innerValue) { - Eval arg = new Ref2DEval(new ReferencePtg((short)1, (short)1, false, false), innerValue); - return invokeT(arg); - } - - private static void confirmText(String text) { - Eval arg = new StringEval(text); - Eval eval = invokeT(arg); - StringEval se = (StringEval) eval; - assertEquals(text, se.getStringValue()); - } - - public void testTextValues() { - - confirmText("abc"); - confirmText(""); - confirmText(" "); - confirmText("~"); - confirmText("123"); - confirmText("TRUE"); - } - - private static void confirmError(Eval arg) { - Eval eval = invokeT(arg); - assertTrue(arg == eval); - } - - public void testErrorValues() { - - confirmError(ErrorEval.VALUE_INVALID); - confirmError(ErrorEval.NA); - confirmError(ErrorEval.REF_INVALID); - } - - private static void confirmString(Eval eval, String expected) { - assertTrue(eval instanceof StringEval); - assertEquals(expected, ((StringEval)eval).getStringValue()); - } - - private static void confirmOther(Eval arg) { - Eval eval = invokeT(arg); - confirmString(eval, ""); - } - - public void testOtherValues() { - confirmOther(new NumberEval(2)); - confirmOther(BoolEval.FALSE); - confirmOther(BlankEval.INSTANCE); // can this particular case be verified? - } - - public void testRefValues() { - Eval eval; - - eval = invokeTWithReference(new StringEval("def")); - confirmString(eval, "def"); - eval = invokeTWithReference(new StringEval(" ")); - confirmString(eval, " "); - - eval = invokeTWithReference(new NumberEval(2)); - confirmString(eval, ""); - eval = invokeTWithReference(BoolEval.TRUE); - confirmString(eval, ""); - - eval = invokeTWithReference(ErrorEval.NAME_INVALID); - assertTrue(eval == ErrorEval.NAME_INVALID); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestTrim.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestTrim.java deleted file mode 100755 index 076ac1fc7e..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestTrim.java +++ /dev/null @@ -1,78 +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 junit.framework.TestCase; - -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.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.StringEval; -/** - * Tests for Excel function TRIM() - * - * @author Josh Micich - */ -public final class TestTrim extends TestCase { - - - private static Eval invokeTrim(Eval text) { - Eval[] args = new Eval[] { text, }; - return new Trim().evaluate(args, -1, (short)-1); - } - - private void confirmTrim(Eval text, String expected) { - Eval result = invokeTrim(text); - assertEquals(StringEval.class, result.getClass()); - assertEquals(expected, ((StringEval)result).getStringValue()); - } - - private void confirmTrim(Eval text, ErrorEval expectedError) { - Eval result = invokeTrim(text); - assertEquals(ErrorEval.class, result.getClass()); - assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); - } - - public void testBasic() { - - confirmTrim(new StringEval(" hi "), "hi"); - confirmTrim(new StringEval("hi "), "hi"); - confirmTrim(new StringEval(" hi"), "hi"); - confirmTrim(new StringEval(" hi there "), "hi there"); - confirmTrim(new StringEval(""), ""); - confirmTrim(new StringEval(" "), ""); - } - - /** - * Valid cases where text arg is not exactly a string - */ - public void testUnusualArgs() { - - // text (first) arg type is number, other args are strings with fractional digits - confirmTrim(new NumberEval(123456), "123456"); - confirmTrim(BoolEval.FALSE, "FALSE"); - confirmTrim(BoolEval.TRUE, "TRUE"); - confirmTrim(BlankEval.INSTANCE, ""); - } - - public void testErrors() { - confirmTrim(ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestXYNumericFunction.java b/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestXYNumericFunction.java deleted file mode 100755 index c9f043bd3b..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/record/formula/functions/TestXYNumericFunction.java +++ /dev/null @@ -1,139 +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 junit.framework.TestCase; - -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.eval.Area2DEval; -import org.apache.poi.hssf.record.formula.eval.ErrorEval; -import org.apache.poi.hssf.record.formula.eval.Eval; -import org.apache.poi.hssf.record.formula.eval.NumberEval; -import org.apache.poi.hssf.record.formula.eval.ValueEval; -/** - * Tests for Excel functions SUMX2MY2(), SUMX2PY2(), SUMXMY2() - * - * @author Josh Micich - */ -public final class TestXYNumericFunction extends TestCase { - private static final Function SUM_SQUARES = new Sumx2py2(); - private static final Function DIFF_SQUARES = new Sumx2my2(); - private static final Function SUM_SQUARES_OF_DIFFS = new Sumxmy2(); - - private static Eval invoke(Function function, Eval xArray, Eval yArray) { - Eval[] args = new Eval[] { xArray, yArray, }; - return function.evaluate(args, -1, (short)-1); - } - - private void confirm(Function function, Eval xArray, Eval yArray, double expected) { - Eval result = invoke(function, xArray, yArray); - assertEquals(NumberEval.class, result.getClass()); - assertEquals(expected, ((NumberEval)result).getNumberValue(), 0); - } - private void confirmError(Function function, Eval xArray, Eval yArray, ErrorEval expectedError) { - Eval result = invoke(function, xArray, yArray); - assertEquals(ErrorEval.class, result.getClass()); - assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); - } - - private void confirmError(Eval xArray, Eval yArray, ErrorEval expectedError) { - confirmError(SUM_SQUARES, xArray, yArray, expectedError); - confirmError(DIFF_SQUARES, xArray, yArray, expectedError); - confirmError(SUM_SQUARES_OF_DIFFS, xArray, yArray, expectedError); - } - - public void testBasic() { - ValueEval[] xValues = { - new NumberEval(1), - new NumberEval(2), - }; - ValueEval areaEvalX = createAreaEval(xValues); - confirm(SUM_SQUARES, areaEvalX, areaEvalX, 10.0); - confirm(DIFF_SQUARES, areaEvalX, areaEvalX, 0.0); - confirm(SUM_SQUARES_OF_DIFFS, areaEvalX, areaEvalX, 0.0); - - ValueEval[] yValues = { - new NumberEval(3), - new NumberEval(4), - }; - ValueEval areaEvalY = createAreaEval(yValues); - confirm(SUM_SQUARES, areaEvalX, areaEvalY, 30.0); - confirm(DIFF_SQUARES, areaEvalX, areaEvalY, -20.0); - confirm(SUM_SQUARES_OF_DIFFS, areaEvalX, areaEvalY, 8.0); - } - - /** - * number of items in array is not limited to 30 - */ - public void testLargeArrays() { - ValueEval[] xValues = createMockNumberArray(100, 3); - ValueEval[] yValues = createMockNumberArray(100, 2); - - confirm(SUM_SQUARES, createAreaEval(xValues), createAreaEval(yValues), 1300.0); - confirm(DIFF_SQUARES, createAreaEval(xValues), createAreaEval(yValues), 500.0); - confirm(SUM_SQUARES_OF_DIFFS, createAreaEval(xValues), createAreaEval(yValues), 100.0); - } - - - private ValueEval[] createMockNumberArray(int size, double value) { - ValueEval[] result = new ValueEval[size]; - for (int i = 0; i < result.length; i++) { - result[i] = new NumberEval(value); - } - return result; - } - - private static ValueEval createAreaEval(ValueEval[] values) { - String refStr = "A1:A" + values.length; - return new Area2DEval(new AreaPtg(refStr), values); - } - - public void testErrors() { - ValueEval[] xValues = { - ErrorEval.REF_INVALID, - new NumberEval(2), - }; - ValueEval areaEvalX = createAreaEval(xValues); - ValueEval[] yValues = { - new NumberEval(2), - ErrorEval.NULL_INTERSECTION, - }; - ValueEval areaEvalY = createAreaEval(yValues); - ValueEval[] zValues = { // wrong size - new NumberEval(2), - }; - ValueEval areaEvalZ = createAreaEval(zValues); - - // if either arg is an error, that error propagates - confirmError(ErrorEval.REF_INVALID, ErrorEval.NAME_INVALID, ErrorEval.REF_INVALID); - confirmError(areaEvalX, ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); - confirmError(ErrorEval.NAME_INVALID, areaEvalX, ErrorEval.NAME_INVALID); - - // array sizes must match - confirmError(areaEvalX, areaEvalZ, ErrorEval.NA); - confirmError(areaEvalZ, areaEvalY, ErrorEval.NA); - - // any error in an array item propagates up - confirmError(areaEvalX, areaEvalX, ErrorEval.REF_INVALID); - - // search for errors array by array, not pair by pair - confirmError(areaEvalX, areaEvalY, ErrorEval.REF_INVALID); - confirmError(areaEvalY, areaEvalX, ErrorEval.NULL_INTERSECTION); - - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java deleted file mode 100644 index c849fd4369..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java +++ /dev/null @@ -1,94 +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.usermodel; - -import java.io.File; -import java.io.FileInputStream; -import java.util.Iterator; -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; -import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; -import org.apache.poi.hssf.util.CellReference; - -public final class TestBug42464 extends TestCase { - String dirname; - - protected void setUp() throws Exception { - super.setUp(); - dirname = System.getProperty("HSSF.testdata.path"); - } - - public void testOKFile() throws Exception { - HSSFWorkbook wb = new HSSFWorkbook( - new FileInputStream(new File(dirname,"42464-ExpPtg-ok.xls")) - ); - process(wb); - } - public void testExpSharedBadFile() throws Exception { - HSSFWorkbook wb = new HSSFWorkbook( - new FileInputStream(new File(dirname,"42464-ExpPtg-bad.xls")) - ); - process(wb); - } - - protected void process(HSSFWorkbook wb) { - for(int i=0; i " + cell.getCellFormula()); - } - - CellValue evalResult = eval.evaluate(cell); - assertNotNull(evalResult); - } - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug43093.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug43093.java deleted file mode 100644 index ce072e9e01..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug43093.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.usermodel; - -import junit.framework.TestCase; - -public class TestBug43093 extends TestCase { - - private static void addNewSheetWithCellsA1toD4(HSSFWorkbook book, int sheet) { - - HSSFSheet sht = book .createSheet("s" + sheet); - for (short r=0; r < 4; r++) { - - HSSFRow row = sht.createRow (r); - for (short c=0; c < 4; c++) { - - HSSFCell cel = row.createCell(c); - /**/ cel.setCellValue(sheet*100 + r*10 + c); - } - } - } - - public void testBug43093() throws Exception { - HSSFWorkbook xlw = new HSSFWorkbook(); - - addNewSheetWithCellsA1toD4(xlw, 1); - addNewSheetWithCellsA1toD4(xlw, 2); - addNewSheetWithCellsA1toD4(xlw, 3); - addNewSheetWithCellsA1toD4(xlw, 4); - - HSSFSheet s2 = xlw.getSheet("s2"); - HSSFRow s2r3 = s2.getRow(3); - HSSFCell s2E4 = s2r3.createCell((short)4); - /**/ s2E4.setCellFormula("SUM(s3!B2:C3)"); - - HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(s2, xlw); - eva.setCurrentRow(s2r3); - double d = eva.evaluate(s2E4).getNumberValue(); - - // internalEvaluate(...) Area3DEval.: 311+312+321+322 expected - assertEquals(d, (double)(311+312+321+322), 0.0000001); - // System.out.println("Area3DEval ok.: 311+312+321+322=" + d); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java deleted file mode 100755 index ce4afd36f6..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.apache.poi.hssf.usermodel; -/* ==================================================================== - 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. -==================================================================== */ - -import junit.framework.TestCase; - -import java.io.IOException; -import java.io.FileInputStream; -import java.io.File; - -/** - * Bug 44297: 32767+32768 is evaluated to -1 - * Fix: IntPtg must operate with unsigned short. Reading signed short results in incorrect formula calculation - * if a formula has values in the interval [Short.MAX_VALUE, (Short.MAX_VALUE+1)*2] - * - * @author Yegor Kozlov - */ - -public class TestBug44297 extends TestCase { - protected String cwd = System.getProperty("HSSF.testdata.path"); - - public void test44297() throws IOException { - FileInputStream in = new FileInputStream(new File(cwd, "44297.xls")); - HSSFWorkbook wb = new HSSFWorkbook(in); - in.close(); - - HSSFRow row; - HSSFCell cell; - - HSSFSheet sheet = wb.getSheetAt(0); - - HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); - - row = (HSSFRow)sheet.getRow(0); - cell = row.getCell((short)0); - assertEquals("31+46", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(77, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(1); - cell = row.getCell((short)0); - assertEquals("30+53", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(83, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(2); - cell = row.getCell((short)0); - assertEquals("SUM(A1:A2)", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(160, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(4); - cell = row.getCell((short)0); - assertEquals("32767+32768", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(7); - cell = row.getCell((short)0); - assertEquals("32744+42333", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(8); - cell = row.getCell((short)0); - assertEquals("327680.0/32768", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(10, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(9); - cell = row.getCell((short)0); - assertEquals("32767+32769", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(10); - cell = row.getCell((short)0); - assertEquals("35000+36000", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0); - - row = (HSSFRow)sheet.getRow(11); - cell = row.getCell((short)0); - assertEquals("-1000000.0-3000000.0", cell.getCellFormula()); - eva.setCurrentRow(row); - assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0); - } - -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44410.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44410.java deleted file mode 100644 index 27c3bdc387..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44410.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.apache.poi.hssf.usermodel; -/* ==================================================================== - 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. -==================================================================== */ - -import junit.framework.TestCase; - -import java.io.IOException; -import java.io.FileInputStream; -import java.io.File; -import java.util.List; - -import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; -import org.apache.poi.hssf.record.formula.AreaPtg; -import org.apache.poi.hssf.record.formula.FuncVarPtg; - -/** - * Bug 44410: SUM(C:C) is valid in excel, and means a sum - * of all the rows in Column C - * - * @author Nick Burch - */ - -public class TestBug44410 extends TestCase { - protected String cwd = System.getProperty("HSSF.testdata.path"); - - public void test44410() throws IOException { - FileInputStream in = new FileInputStream(new File(cwd, "SingleLetterRanges.xls")); - HSSFWorkbook wb = new HSSFWorkbook(in); - in.close(); - - HSSFSheet sheet = wb.getSheetAt(0); - - HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); - - // =index(C:C,2,1) -> 2 - HSSFRow rowIDX = (HSSFRow)sheet.getRow(3); - // =sum(C:C) -> 6 - HSSFRow rowSUM = (HSSFRow)sheet.getRow(4); - // =sum(C:D) -> 66 - HSSFRow rowSUM2D = (HSSFRow)sheet.getRow(5); - - // Test the sum - HSSFCell cellSUM = rowSUM.getCell((short)0); - - FormulaRecordAggregate frec = - (FormulaRecordAggregate)cellSUM.getCellValueRecord(); - List ops = frec.getFormulaRecord().getParsedExpression(); - assertEquals(2, ops.size()); - assertEquals(AreaPtg.class, ops.get(0).getClass()); - assertEquals(FuncVarPtg.class, ops.get(1).getClass()); - - // Actually stored as C1 to C65536 - // (last row is -1 === 65535) - AreaPtg ptg = (AreaPtg)ops.get(0); - assertEquals(2, ptg.getFirstColumn()); - assertEquals(2, ptg.getLastColumn()); - assertEquals(0, ptg.getFirstRow()); - assertEquals(65535, ptg.getLastRow()); - assertEquals("C:C", ptg.toFormulaString(wb.getWorkbook())); - - // Will show as C:C, but won't know how many - // rows it covers as we don't have the sheet - // to hand when turning the Ptgs into a string - assertEquals("SUM(C:C)", cellSUM.getCellFormula()); - eva.setCurrentRow(rowSUM); - - // But the evaluator knows the sheet, so it - // can do it properly - assertEquals(6, eva.evaluate(cellSUM).getNumberValue(), 0); - - - // Test the index - // Again, the formula string will be right but - // lacking row count, evaluated will be right - HSSFCell cellIDX = rowIDX.getCell((short)0); - assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula()); - eva.setCurrentRow(rowIDX); - assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0); - - // Across two colums - HSSFCell cellSUM2D = rowSUM2D.getCell((short)0); - assertEquals("SUM(C:D)", cellSUM2D.getCellFormula()); - eva.setCurrentRow(rowSUM2D); - assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44508.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44508.java deleted file mode 100644 index 3362f3c3e7..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44508.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.apache.poi.hssf.usermodel; -/* ==================================================================== - 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. -==================================================================== */ - -import junit.framework.TestCase; - -public class TestBug44508 extends TestCase { - protected String cwd = System.getProperty("HSSF.testdata.path"); - - public void testEvaluateBooleanInCell_bug44508() { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet(); - wb.setSheetName(0, "Sheet1"); - HSSFRow row = sheet.createRow(0); - HSSFCell cell = row.createCell((short)0); - - cell.setCellFormula("1=1"); - - HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); - fe.setCurrentRow(row); - try { - fe.evaluateInCell(cell); - } catch (NumberFormatException e) { - fail("Identified bug 44508"); - } - assertEquals(true, cell.getBooleanCellValue()); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java deleted file mode 100644 index db4be7f410..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java +++ /dev/null @@ -1,88 +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.usermodel; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.util.Iterator; - -import junit.framework.TestCase; - -public final class TestFormulaEvaluatorBugs extends TestCase { - private String dirName; - private String tmpDirName; - - protected void setUp() throws Exception { - super.setUp(); - dirName = System.getProperty("HSSF.testdata.path"); - tmpDirName = System.getProperty("java.io.tmpdir"); - } - - /** - * An odd problem with evaluateFormulaCell giving the - * right values when file is opened, but changes - * to the source data in some versions of excel - * doesn't cause them to be updated. However, other - * versions of excel, and gnumeric, work just fine - * WARNING - tedious bug where you actually have to - * open up excel - */ - public void test44636() throws Exception { - // Open the existing file, tweak one value and - // re-calculate - FileInputStream in = new FileInputStream(new File(dirName,"44636.xls")); - HSSFWorkbook wb = new HSSFWorkbook(in); - HSSFSheet sheet = wb.getSheetAt (0); - HSSFRow row = sheet.getRow (0); - - row.getCell((short)0).setCellValue(4.2); - row.getCell((short)2).setCellValue(25); - - HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - assertEquals(4.2*25, row.getCell((short)3).getNumericCellValue(), 0.0001); - - // Save - File existing = new File(tmpDirName,"44636-existing.xls"); - FileOutputStream out = new FileOutputStream(existing); - wb.write(out); - out.close(); - System.err.println("Existing file for bug #44636 written to " + existing.toString()); - - - // Now, do a new file from scratch - wb = new HSSFWorkbook(); - sheet = wb.createSheet(); - - row = sheet.createRow(0); - row.createCell((short)0).setCellValue(1.2); - row.createCell((short)1).setCellValue(4.2); - - row = sheet.createRow(1); - row.createCell((short)0).setCellFormula("SUM(A1:B1)"); - - HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); - assertEquals(5.4, row.getCell((short)0).getNumericCellValue(), 0.0001); - - // Save - File scratch = new File(tmpDirName,"44636-scratch.xls"); - out = new FileOutputStream(scratch); - wb.write(out); - out.close(); - System.err.println("New file for bug #44636 written to " + scratch.toString()); - } -} diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java deleted file mode 100644 index 6c2e3b6412..0000000000 --- a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.apache.poi.hssf.usermodel; - -import java.util.Iterator; - -import junit.framework.TestCase; - -/** - * Tests to show that our documentation at - * http://poi.apache.org/hssf/eval.html - * all actually works as we'd expect them to - */ -public class TestFormulaEvaluatorDocs extends TestCase { - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * http://poi.apache.org/hssf/eval.html#EvaluateAll - */ - public void testEvaluateAll() throws Exception { - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet s1 = wb.createSheet(); - HSSFSheet s2 = wb.createSheet(); - wb.setSheetName(0, "S1"); - wb.setSheetName(1, "S2"); - - HSSFRow s1r1 = s1.createRow(0); - HSSFRow s1r2 = s1.createRow(1); - HSSFRow s2r1 = s2.createRow(0); - - HSSFCell s1r1c1 = s1r1.createCell((short)0); - HSSFCell s1r1c2 = s1r1.createCell((short)1); - HSSFCell s1r1c3 = s1r1.createCell((short)2); - s1r1c1.setCellValue(22.3); - s1r1c2.setCellValue(33.4); - s1r1c3.setCellFormula("SUM(A1:B1)"); - - HSSFCell s1r2c1 = s1r2.createCell((short)0); - HSSFCell s1r2c2 = s1r2.createCell((short)1); - HSSFCell s1r2c3 = s1r2.createCell((short)2); - s1r2c1.setCellValue(-1.2); - s1r2c2.setCellValue(-3.4); - s1r2c3.setCellFormula("SUM(A2:B2)"); - - HSSFCell s2r1c1 = s2r1.createCell((short)0); - s2r1c1.setCellFormula("S1!A1"); - - // Not evaluated yet - assertEquals(0.0, s1r1c3.getNumericCellValue(), 0); - assertEquals(0.0, s1r2c3.getNumericCellValue(), 0); - assertEquals(0.0, s2r1c1.getNumericCellValue(), 0); - - // Do a full evaluate, as per our docs - // uses evaluateFormulaCell() - for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) { - HSSFSheet sheet = wb.getSheetAt(sheetNum); - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); - - for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { - HSSFRow r = (HSSFRow)rit.next(); - evaluator.setCurrentRow(r); - - for(Iterator cit = r.cellIterator(); cit.hasNext();) { - HSSFCell c = (HSSFCell)cit.next(); - if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) { - evaluator.evaluateFormulaCell(c); - - // For testing - all should be numeric - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, evaluator.evaluateFormulaCell(c)); - } - } - } - } - - // Check now as expected - assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0); - assertEquals("SUM(A1:B1)", wb.getSheetAt(0).getRow(0).getCell((short)2).getCellFormula()); - assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType()); - - assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0); - assertEquals("SUM(A2:B2)", wb.getSheetAt(0).getRow(1).getCell((short)2).getCellFormula()); - assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType()); - - assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0); - assertEquals("'S1'!A1", wb.getSheetAt(1).getRow(0).getCell((short)0).getCellFormula()); - assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType()); - - - // Now do the alternate call, which zaps the formulas - // uses evaluateInCell() - for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) { - HSSFSheet sheet = wb.getSheetAt(sheetNum); - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); - - for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { - HSSFRow r = (HSSFRow)rit.next(); - evaluator.setCurrentRow(r); - - for(Iterator cit = r.cellIterator(); cit.hasNext();) { - HSSFCell c = (HSSFCell)cit.next(); - if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) { - evaluator.evaluateInCell(c); - } - } - } - } - - assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0); - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType()); - - assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0); - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType()); - - assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0); - assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType()); - } -} diff --git a/src/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java b/src/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java new file mode 100644 index 0000000000..a038a964ee --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/eventusermodel/TestMissingRecordAwareHSSFListener.java @@ -0,0 +1,360 @@ +/* ==================================================================== + 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.eventusermodel; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; +import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; +import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingRowDummyRecord; +import org.apache.poi.hssf.record.LabelSSTRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RowRecord; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +/** + * Tests for MissingRecordAwareHSSFListener + */ +public final class TestMissingRecordAwareHSSFListener extends TestCase { + + private Record[] r; + + public void setUp() { + String dirname = System.getProperty("HSSF.testdata.path"); + File f = new File(dirname + "/MissingBits.xls"); + + HSSFRequest req = new HSSFRequest(); + MockHSSFListener mockListen = new MockHSSFListener(); + MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(mockListen); + req.addListenerForAllRecords(listener); + + HSSFEventFactory factory = new HSSFEventFactory(); + try { + POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(f)); + factory.processWorkbookEvents(req, fs); + } catch (IOException e) { + throw new RuntimeException(e); + } + r = mockListen.getRecords(); + } + + public void testMissingRowRecords() throws Exception { + + // We have rows 0, 1, 2, 20 and 21 + int row0 = -1; + for(int i=0; i -1); + + // Following row 0, we should have 1, 2, then dummy, then 20+21+22 + assertTrue(r[row0] instanceof RowRecord); + assertTrue(r[row0+1] instanceof RowRecord); + assertTrue(r[row0+2] instanceof RowRecord); + assertTrue(r[row0+3] instanceof MissingRowDummyRecord); + assertTrue(r[row0+4] instanceof MissingRowDummyRecord); + assertTrue(r[row0+5] instanceof MissingRowDummyRecord); + assertTrue(r[row0+6] instanceof MissingRowDummyRecord); + // ... + assertTrue(r[row0+18] instanceof MissingRowDummyRecord); + assertTrue(r[row0+19] instanceof MissingRowDummyRecord); + assertTrue(r[row0+20] instanceof RowRecord); + assertTrue(r[row0+21] instanceof RowRecord); + assertTrue(r[row0+22] instanceof RowRecord); + + // Check things had the right row numbers + RowRecord rr; + rr = (RowRecord)r[row0+2]; + assertEquals(2, rr.getRowNumber()); + rr = (RowRecord)r[row0+20]; + assertEquals(20, rr.getRowNumber()); + rr = (RowRecord)r[row0+21]; + assertEquals(21, rr.getRowNumber()); + + MissingRowDummyRecord mr; + mr = (MissingRowDummyRecord)r[row0+3]; + assertEquals(3, mr.getRowNumber()); + mr = (MissingRowDummyRecord)r[row0+4]; + assertEquals(4, mr.getRowNumber()); + mr = (MissingRowDummyRecord)r[row0+5]; + assertEquals(5, mr.getRowNumber()); + mr = (MissingRowDummyRecord)r[row0+18]; + assertEquals(18, mr.getRowNumber()); + mr = (MissingRowDummyRecord)r[row0+19]; + assertEquals(19, mr.getRowNumber()); + } + + public void testEndOfRowRecords() throws Exception { + + // Find the cell at 0,0 + int cell00 = -1; + for(int i=0; i -1); + + // We have rows 0, 1, 2, 20 and 21 + // Row 0 has 1 entry + // Row 1 has 4 entries + // Row 2 has 6 entries + // Row 20 has 5 entries + // Row 21 has 7 entries + // Row 22 has 12 entries + + // Row 0 + assertFalse(r[cell00+0] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+1] instanceof LastCellOfRowDummyRecord); + // Row 1 + assertFalse(r[cell00+2] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+3] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+4] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+5] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+6] instanceof LastCellOfRowDummyRecord); + // Row 2 + assertFalse(r[cell00+7] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+8] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+9] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+10] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+11] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+12] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+13] instanceof LastCellOfRowDummyRecord); + // Row 3 -> 19 + assertTrue(r[cell00+14] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+15] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+16] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+17] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+18] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+19] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+20] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+21] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+22] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+23] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+24] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+25] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+26] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+27] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+28] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+29] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+30] instanceof LastCellOfRowDummyRecord); + // Row 20 + assertFalse(r[cell00+31] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+32] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+33] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+34] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+35] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+36] instanceof LastCellOfRowDummyRecord); + // Row 21 + assertFalse(r[cell00+37] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+38] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+39] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+40] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+41] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+42] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+43] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+44] instanceof LastCellOfRowDummyRecord); + // Row 22 + assertFalse(r[cell00+45] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+46] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+47] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+48] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+49] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+50] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+51] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+52] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+53] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+54] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+55] instanceof LastCellOfRowDummyRecord); + assertFalse(r[cell00+56] instanceof LastCellOfRowDummyRecord); + assertTrue(r[cell00+57] instanceof LastCellOfRowDummyRecord); + + // Check the numbers of the last seen columns + LastCellOfRowDummyRecord[] lrs = new LastCellOfRowDummyRecord[23]; + int lrscount = 0; + for(int i=0; i -1); + + // We have rows 0, 1, 2, 20 and 21 + // Row 0 has 1 entry, 0 + // Row 1 has 4 entries, 0+3 + // Row 2 has 6 entries, 0+5 + // Row 20 has 5 entries, 0-5 + // Row 21 has 7 entries, 0+1+3+5+6 + // Row 22 has 12 entries, 0+3+4+11 + + // Row 0 + assertFalse(r[cell00+0] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+1] instanceof MissingCellDummyRecord); + + // Row 1 + assertFalse(r[cell00+2] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+3] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+4] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+5] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+6] instanceof MissingCellDummyRecord); + + // Row 2 + assertFalse(r[cell00+7] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+8] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+9] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+10] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+11] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+12] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+13] instanceof MissingCellDummyRecord); + + // Row 3-19 + assertFalse(r[cell00+14] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+15] instanceof MissingCellDummyRecord); + + // Row 20 + assertFalse(r[cell00+31] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+32] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+33] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+34] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+35] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+36] instanceof MissingCellDummyRecord); + + // Row 21 + assertFalse(r[cell00+37] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+38] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+39] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+40] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+41] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+42] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+43] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+44] instanceof MissingCellDummyRecord); + + // Row 22 + assertFalse(r[cell00+45] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+46] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+47] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+48] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+49] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+50] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+51] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+52] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+53] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+54] instanceof MissingCellDummyRecord); + assertTrue(r[cell00+55] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+56] instanceof MissingCellDummyRecord); + assertFalse(r[cell00+57] instanceof MissingCellDummyRecord); + + // Check some numbers + MissingCellDummyRecord mc; + + mc = (MissingCellDummyRecord)r[cell00+3]; + assertEquals(1, mc.getRow()); + assertEquals(1, mc.getColumn()); + mc = (MissingCellDummyRecord)r[cell00+4]; + assertEquals(1, mc.getRow()); + assertEquals(2, mc.getColumn()); + + mc = (MissingCellDummyRecord)r[cell00+8]; + assertEquals(2, mc.getRow()); + assertEquals(1, mc.getColumn()); + mc = (MissingCellDummyRecord)r[cell00+9]; + assertEquals(2, mc.getRow()); + assertEquals(2, mc.getColumn()); + + mc = (MissingCellDummyRecord)r[cell00+55]; + assertEquals(22, mc.getRow()); + assertEquals(10, mc.getColumn()); + } + + private static final class MockHSSFListener implements HSSFListener { + public MockHSSFListener() {} + private final List _records = new ArrayList(); + + public void processRecord(Record record) { + _records.add(record); + + if(record instanceof MissingRowDummyRecord) { + MissingRowDummyRecord mr = (MissingRowDummyRecord)record; + log("Got dummy row " + mr.getRowNumber()); + } + if(record instanceof MissingCellDummyRecord) { + MissingCellDummyRecord mc = (MissingCellDummyRecord)record; + log("Got dummy cell " + mc.getRow() + " " + mc.getColumn()); + } + if(record instanceof LastCellOfRowDummyRecord) { + LastCellOfRowDummyRecord lc = (LastCellOfRowDummyRecord)record; + log("Got end-of row, row was " + lc.getRow() + ", last column was " + lc.getLastColumnNumber()); + } + } + private static void log(String msg) { + if(false) { // successful tests should be quiet + System.out.println(msg); + } + } + public Record[] getRecords() { + Record[] result = new Record[_records.size()]; + _records.toArray(result); + return result; + } + } +} diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java new file mode 100644 index 0000000000..7419734535 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParserEval.java @@ -0,0 +1,110 @@ +/* ==================================================================== + 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.model; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.model.FormulaParser.FormulaParseException; +import org.apache.poi.hssf.record.formula.FuncVarPtg; +import org.apache.poi.hssf.record.formula.NamePtg; +import org.apache.poi.hssf.record.formula.Ptg; +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFName; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; + +/** + * Test the low level formula parser functionality, + * but using parts which need to use + * HSSFFormulaEvaluator. + */ +public final class TestFormulaParserEval extends TestCase { + + public void testWithNamedRange() throws Exception { + HSSFWorkbook workbook = new HSSFWorkbook(); + FormulaParser fp; + Ptg[] ptgs; + + HSSFSheet s = workbook.createSheet("Foo"); + s.createRow(0).createCell((short)0).setCellValue(1.1); + s.createRow(1).createCell((short)0).setCellValue(2.3); + s.createRow(2).createCell((short)2).setCellValue(3.1); + + HSSFName name = workbook.createName(); + name.setNameName("testName"); + name.setReference("A1:A2"); + + fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); + fp.parse(); + ptgs = fp.getRPNPtg(); + assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); + assertEquals(NamePtg.class, ptgs[0].getClass()); + assertEquals(FuncVarPtg.class, ptgs[1].getClass()); + + // Now make it a single cell + name.setReference("C3"); + + fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); + fp.parse(); + ptgs = fp.getRPNPtg(); + assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); + assertEquals(NamePtg.class, ptgs[0].getClass()); + assertEquals(FuncVarPtg.class, ptgs[1].getClass()); + + // And make it non-contiguous + name.setReference("A1:A2,C3"); + fp = HSSFFormulaEvaluator.getUnderlyingParser(workbook, "SUM(testName)"); + fp.parse(); + ptgs = fp.getRPNPtg(); + assertTrue("two tokens expected, got "+ptgs.length,ptgs.length == 2); + assertEquals(NamePtg.class, ptgs[0].getClass()); + assertEquals(FuncVarPtg.class, ptgs[1].getClass()); + } + + public void testEvaluateFormulaWithRowBeyond32768_Bug44539() { + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet(); + wb.setSheetName(0, "Sheet1"); + + HSSFRow row = sheet.createRow(0); + HSSFCell cell = row.createCell((short)0); + cell.setCellFormula("SUM(A32769:A32770)"); + + // put some values in the cells to make the evaluation more interesting + sheet.createRow(32768).createCell((short)0).setCellValue(31); + sheet.createRow(32769).createCell((short)0).setCellValue(11); + + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + fe.setCurrentRow(row); + CellValue result; + try { + result = fe.evaluate(cell); + } catch (FormulaParseException e) { + if(e.getMessage().equals("Found reference to named range \"A\", but that named range wasn't defined!")) { + fail("Identifed bug 44539"); + } + throw new RuntimeException(e); + } + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, result.getCellType()); + assertEquals(42.0, result.getNumberValue(), 0.0); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java new file mode 100755 index 0000000000..5098c789a7 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java @@ -0,0 +1,40 @@ +/* ==================================================================== + 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 junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Collects all tests the package org.apache.poi.hssf.record.formula.eval. + * + * @author Josh Micich + */ +public class AllFormulaEvalTests { + + public static Test suite() { + TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.eval"); + result.addTestSuite(TestCircularReferences.class); + result.addTestSuite(TestExternalFunction.class); + result.addTestSuite(TestFormulaBugs.class); + result.addTestSuite(TestFormulasFromSpreadsheet.class); + result.addTestSuite(TestPercentEval.class); + result.addTestSuite(TestUnaryPlusEval.class); + return result; + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java new file mode 100755 index 0000000000..72db658f77 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestCircularReferences.java @@ -0,0 +1,125 @@ +/* ==================================================================== + 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 junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; +/** + * Tests HSSFFormulaEvaluator for its handling of cell formula circular references. + * + * @author Josh Micich + */ +public final class TestCircularReferences extends TestCase { + /** + * Translates StackOverflowError into AssertionFailedError + */ + private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFSheet sheet, HSSFRow row, HSSFCell testCell) + throws AssertionFailedError { + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + evaluator.setCurrentRow(row); + try { + return evaluator.evaluate(testCell); + } catch (StackOverflowError e) { + throw new AssertionFailedError( "circular reference caused stack overflow error"); + } + } + /** + * Makes sure that the specified evaluated cell value represents a circular reference error. + */ + private static void confirmCycleErrorCode(CellValue cellValue) { + assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_ERROR); + assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cellValue.getErrorValue()); + } + + + /** + * ASF Bugzilla Bug 44413 + * "INDEX() formula cannot contain its own location in the data array range" + */ + public void testIndexFormula() { + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet("Sheet1"); + + short colB = 1; + sheet.createRow(0).createCell(colB).setCellValue(1); + sheet.createRow(1).createCell(colB).setCellValue(2); + sheet.createRow(2).createCell(colB).setCellValue(3); + HSSFRow row4 = sheet.createRow(3); + HSSFCell testCell = row4.createCell((short)0); + // This formula should evaluate to the contents of B2, + testCell.setCellFormula("INDEX(A1:B4,2,2)"); + // However the range A1:B4 also includes the current cell A4. If the other parameters + // were 4 and 1, this would represent a circular reference. Since POI 'fully' evaluates + // arguments before invoking operators, POI must handle such potential cycles gracefully. + + + CellValue cellValue = evaluateWithCycles(wb, sheet, row4, testCell); + + assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_NUMERIC); + assertEquals(2, cellValue.getNumberValue(), 0); + } + + /** + * Cell A1 has formula "=A1" + */ + public void testSimpleCircularReference() { + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet("Sheet1"); + + HSSFRow row = sheet.createRow(0); + HSSFCell testCell = row.createCell((short)0); + testCell.setCellFormula("A1"); + + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + evaluator.setCurrentRow(row); + CellValue cellValue = evaluateWithCycles(wb, sheet, row, testCell); + + confirmCycleErrorCode(cellValue); + } + + /** + * A1=B1, B1=C1, C1=D1, D1=A1 + */ + public void testMultiLevelCircularReference() { + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet("Sheet1"); + + HSSFRow row = sheet.createRow(0); + row.createCell((short)0).setCellFormula("B1"); + row.createCell((short)1).setCellFormula("C1"); + row.createCell((short)2).setCellFormula("D1"); + HSSFCell testCell = row.createCell((short)3); + testCell.setCellFormula("A1"); + + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + evaluator.setCurrentRow(row); + CellValue cellValue = evaluateWithCycles(wb, sheet, row, testCell); + + confirmCycleErrorCode(cellValue); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java new file mode 100755 index 0000000000..27e3338652 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestExternalFunction.java @@ -0,0 +1,61 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFName; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; +/** + * + * @author Josh Micich + */ +public final class TestExternalFunction extends TestCase { + + /** + * Checks that an external function can get invoked from the formula evaluator. + */ + public void testInvoke() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet(); + wb.setSheetName(0, "Sheet1"); + HSSFRow row = sheet.createRow(0); + HSSFCell cell = row.createCell((short)0); + + HSSFName hssfName = wb.createName(); + hssfName.setNameName("myFunc"); + + cell.setCellFormula("myFunc()"); + String actualFormula=cell.getCellFormula(); + assertEquals("myFunc()", actualFormula); + + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + fe.setCurrentRow(row); + CellValue evalResult = fe.evaluate(cell); + + // Check the return value from ExternalFunction.evaluate() + // TODO - make this test assert something more interesting as soon as ExternalFunction works a bit better + assertEquals(HSSFCell.CELL_TYPE_ERROR, evalResult.getCellType()); + assertEquals(ErrorEval.FUNCTION_NOT_IMPLEMENTED.getErrorCode(), evalResult.getErrorValue()); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java new file mode 100755 index 0000000000..617f5d0d4e --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulaBugs.java @@ -0,0 +1,217 @@ +/* ==================================================================== + 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.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; + +/** + * Miscellaneous tests for bugzilla entries.

    The test name contains the + * bugzilla bug id. + * + * + * @author Josh Micich + */ +public final class TestFormulaBugs extends TestCase { + + private static final String TEST_DATA_DIR_SYS_PROPERTY_NAME = "HSSF.testdata.path"; + + /** + * Opens a sample file from the standard HSSF test data directory + * + * @return an open InputStream for the specified sample file + */ + private static InputStream openSampleFileStream(String sampleFileName) { + // TODO - move this method somewhere common + String dataDirName = System + .getProperty(TEST_DATA_DIR_SYS_PROPERTY_NAME); + if (dataDirName == null) { + throw new RuntimeException("Must set system property '" + + TEST_DATA_DIR_SYS_PROPERTY_NAME + + "' before running tests"); + } + File dataDir = new File(dataDirName); + if (!dataDir.exists()) { + throw new RuntimeException("Data dir '" + dataDirName + + "' specified by system property '" + + TEST_DATA_DIR_SYS_PROPERTY_NAME + "' does not exist"); + } + File f = new File(dataDir, sampleFileName); + if (!f.exists()) { + throw new RuntimeException("Sample file '" + sampleFileName + + "' not found in data dir '" + dataDirName + "'"); + } + InputStream is; + try { + is = new FileInputStream(f); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + return is; + } + + /** + * Bug 27349 - VLOOKUP with reference to another sheet.

    This test was + * added long after the relevant functionality was fixed. + */ + public void test27349() { + // 27349-vlookupAcrossSheets.xls is bugzilla/attachment.cgi?id=10622 + InputStream is = openSampleFileStream("27349-vlookupAcrossSheets.xls"); + HSSFWorkbook wb; + try { + // original bug may have thrown exception here, or output warning to + // stderr + wb = new HSSFWorkbook(is); + } catch (IOException e) { + throw new RuntimeException(e); + } + + HSSFSheet sheet = wb.getSheetAt(0); + HSSFRow row = sheet.getRow(1); + HSSFCell cell = row.getCell(0); + + // this definitely would have failed due to 27349 + assertEquals("VLOOKUP(1,'DATA TABLE'!$A$8:'DATA TABLE'!$B$10,2)", cell + .getCellFormula()); + + // We might as well evaluate the formula + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + fe.setCurrentRow(row); + CellValue cv = fe.evaluate(cell); + + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); + assertEquals(3.0, cv.getNumberValue(), 0.0); + } + + /** + * Bug 27405 - isnumber() formula always evaluates to false in if statement

    + * + * seems to be a duplicate of 24925 + */ + public void test27405() { + + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet("input"); + // input row 0 + HSSFRow row = sheet.createRow((short) 0); + HSSFCell cell = row.createCell((short) 0); + cell = row.createCell((short) 1); + cell.setCellValue(1); // B1 + // input row 1 + row = sheet.createRow((short) 1); + cell = row.createCell((short) 1); + cell.setCellValue(999); // B2 + + int rno = 4; + row = sheet.createRow(rno); + cell = row.createCell((short) 1); // B5 + cell.setCellFormula("isnumber(b1)"); + cell = row.createCell((short) 3); // D5 + cell.setCellFormula("IF(ISNUMBER(b1),b1,b2)"); + + if (false) { // set true to check excel file manually + // bug report mentions 'Editing the formula in excel "fixes" the problem.' + try { + FileOutputStream fileOut = new FileOutputStream("27405output.xls"); + wb.write(fileOut); + fileOut.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + // use POI's evaluator as an extra sanity check + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + fe.setCurrentRow(row); + CellValue cv; + cv = fe.evaluate(cell); + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); + assertEquals(1.0, cv.getNumberValue(), 0.0); + + cv = fe.evaluate(row.getCell(1)); + assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, cv.getCellType()); + assertEquals(true, cv.getBooleanValue()); + } + + /** + * Bug 42448 - Can't parse SUMPRODUCT(A!C7:A!C67, B8:B68) / B69

    + */ + public void test42448() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet1 = wb.createSheet("Sheet1"); + + HSSFRow row = sheet1.createRow(0); + HSSFCell cell = row.createCell((short) 0); + + // it's important to create the referenced sheet first + HSSFSheet sheet2 = wb.createSheet("A"); // note name 'A' + // TODO - POI crashes if the formula is added before this sheet + // RuntimeException("Zero length string is an invalid sheet name") + // Excel doesn't crash but the formula doesn't work until it is + // re-entered + + String inputFormula = "SUMPRODUCT(A!C7:A!C67, B8:B68) / B69"; // as per bug report + try { + cell.setCellFormula(inputFormula); + } catch (StringIndexOutOfBoundsException e) { + throw new AssertionFailedError("Identified bug 42448"); + } + + assertEquals("SUMPRODUCT(A!C7:C67,B8:B68)/B69", cell.getCellFormula()); + + // might as well evaluate the sucker... + + addCell(sheet2, 5, 2, 3.0); // A!C6 + addCell(sheet2, 6, 2, 4.0); // A!C7 + addCell(sheet2, 66, 2, 5.0); // A!C67 + addCell(sheet2, 67, 2, 6.0); // A!C68 + + addCell(sheet1, 6, 1, 7.0); // B7 + addCell(sheet1, 7, 1, 8.0); // B8 + addCell(sheet1, 67, 1, 9.0); // B68 + addCell(sheet1, 68, 1, 10.0); // B69 + + double expectedResult = (4.0 * 8.0 + 5.0 * 9.0) / 10.0; + + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb); + fe.setCurrentRow(row); + CellValue cv = fe.evaluate(cell); + + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); + assertEquals(expectedResult, cv.getNumberValue(), 0.0); + } + + private static void addCell(HSSFSheet sheet, int rowIx, int colIx, + double value) { + sheet.createRow(rowIx).createCell((short) colIx).setCellValue(value); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java new file mode 100644 index 0000000000..2d5408c76a --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestFormulasFromSpreadsheet.java @@ -0,0 +1,328 @@ +/* +* 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.io.FileInputStream; +import java.io.PrintStream; + +import junit.framework.Assert; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.functions.TestMathX; +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; + +/** + * Tests formulas and operators as loaded from a test data spreadsheet.

    + * This class does not test implementors of Function and OperationEval in + * isolation. Much of the evaluation engine (i.e. HSSFFormulaEvaluator, ...) gets + * exercised as well. Tests for bug fixes and specific/tricky behaviour can be found in the + * corresponding test class (TestXxxx) of the target (Xxxx) implementor, + * where execution can be observed more easily. + * + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + */ +public final class TestFormulasFromSpreadsheet extends TestCase { + + private static final class Result { + public static final int SOME_EVALUATIONS_FAILED = -1; + public static final int ALL_EVALUATIONS_SUCCEEDED = +1; + public static final int NO_EVALUATIONS_FOUND = 0; + } + + /** + * This class defines constants for navigating around the test data spreadsheet used for these tests. + */ + private static final class SS { + + /** + * Name of the test spreadsheet (found in the standard test data folder) + */ + public final static String FILENAME = "FormulaEvalTestData.xls"; + /** + * Row (zero-based) in the test spreadsheet where the operator examples start. + */ + public static final int START_OPERATORS_ROW_INDEX = 22; // Row '23' + /** + * Row (zero-based) in the test spreadsheet where the function examples start. + */ + public static final int START_FUNCTIONS_ROW_INDEX = 87; // Row '88' + /** + * Index of the column that contains the function names + */ + public static final short COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B' + + /** + * Used to indicate when there are no more functions left + */ + public static final String FUNCTION_NAMES_END_SENTINEL = ""; + + /** + * Index of the column where the test values start (for each function) + */ + public static final short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D' + + /** + * Each function takes 4 rows in the test spreadsheet + */ + public static final int NUMBER_OF_ROWS_PER_FUNCTION = 4; + } + + private HSSFWorkbook workbook; + private HSSFSheet sheet; + // Note - multiple failures are aggregated before ending. + // If one or more functions fail, a single AssertionFailedError is thrown at the end + private int _functionFailureCount; + private int _functionSuccessCount; + private int _evaluationFailureCount; + private int _evaluationSuccessCount; + + private static final HSSFCell getExpectedValueCell(HSSFRow row, short columnIndex) { + if (row == null) { + return null; + } + return row.getCell(columnIndex); + } + + + private static void confirmExpectedResult(String msg, HSSFCell expected, HSSFFormulaEvaluator.CellValue actual) { + if (expected == null) { + throw new AssertionFailedError(msg + " - Bad setup data expected value is null"); + } + if(actual == null) { + throw new AssertionFailedError(msg + " - actual value was null"); + } + + if (expected.getCellType() == HSSFCell.CELL_TYPE_STRING) { + String value = expected.getRichStringCellValue().getString(); + if (value.startsWith("#")) { + // TODO - this code never called + expected.setCellType(HSSFCell.CELL_TYPE_ERROR); + // expected.setCellErrorValue(...?); + } + } + + switch (expected.getCellType()) { + case HSSFCell.CELL_TYPE_BLANK: + assertEquals(msg, HSSFCell.CELL_TYPE_BLANK, actual.getCellType()); + break; + case HSSFCell.CELL_TYPE_BOOLEAN: + assertEquals(msg, HSSFCell.CELL_TYPE_BOOLEAN, actual.getCellType()); + assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue()); + break; + case HSSFCell.CELL_TYPE_ERROR: + assertEquals(msg, HSSFCell.CELL_TYPE_ERROR, actual.getCellType()); + if(false) { // TODO: fix ~45 functions which are currently returning incorrect error values + assertEquals(msg, expected.getErrorCellValue(), actual.getErrorValue()); + } + break; + case HSSFCell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation + throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg); + case HSSFCell.CELL_TYPE_NUMERIC: + assertEquals(msg, HSSFCell.CELL_TYPE_NUMERIC, actual.getCellType()); + TestMathX.assertEquals(msg, expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR); +// double delta = Math.abs(expected.getNumericCellValue()-actual.getNumberValue()); +// double pctExpected = Math.abs(0.00001*expected.getNumericCellValue()); +// assertTrue(msg, delta <= pctExpected); + break; + case HSSFCell.CELL_TYPE_STRING: + assertEquals(msg, HSSFCell.CELL_TYPE_STRING, actual.getCellType()); + assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getRichTextStringValue().getString()); + break; + } + } + + + protected void setUp() throws Exception { + if (workbook == null) { + String filePath = System.getProperty("HSSF.testdata.path")+ "/" + SS.FILENAME; + FileInputStream fin = new FileInputStream( filePath ); + workbook = new HSSFWorkbook( fin ); + sheet = workbook.getSheetAt( 0 ); + } + _functionFailureCount = 0; + _functionSuccessCount = 0; + _evaluationFailureCount = 0; + _evaluationSuccessCount = 0; + } + + public void testFunctionsFromTestSpreadsheet() { + + processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, null); + processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, null); + // example for debugging individual functions/operators: +// processFunctionGroup(SS.START_OPERATORS_ROW_INDEX, "ConcatEval"); +// processFunctionGroup(SS.START_FUNCTIONS_ROW_INDEX, "AVERAGE"); + + // confirm results + String successMsg = "There were " + + _evaluationSuccessCount + " successful evaluation(s) and " + + _functionSuccessCount + " function(s) without error"; + if(_functionFailureCount > 0) { + String msg = _functionFailureCount + " function(s) failed in " + + _evaluationFailureCount + " evaluation(s). " + successMsg; + throw new AssertionFailedError(msg); + } + if(false) { // normally no output for successful tests + System.out.println(getClass().getName() + ": " + successMsg); + } + } + + /** + * @param startRowIndex row index in the spreadsheet where the first function/operator is found + * @param testFocusFunctionName name of a single function/operator to test alone. + * Typically pass null to test all functions + */ + private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) { + + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook); + + int rowIndex = startRowIndex; + while (true) { + HSSFRow r = sheet.getRow(rowIndex); + String targetFunctionName = getTargetFunctionName(r); + if(targetFunctionName == null) { + throw new AssertionFailedError("Test spreadsheet cell empty on row (" + + (rowIndex+1) + "). Expected function name or '" + + SS.FUNCTION_NAMES_END_SENTINEL + "'"); + } + if(targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) { + // found end of functions list + break; + } + if(testFocusFunctionName == null || targetFunctionName.equalsIgnoreCase(testFocusFunctionName)) { + + // expected results are on the row below + HSSFRow expectedValuesRow = sheet.getRow(rowIndex + 1); + if(expectedValuesRow == null) { + int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row + throw new AssertionFailedError("Missing expected values row for function '" + + targetFunctionName + " (row " + missingRowNum + ")"); + } + switch(processFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow)) { + case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break; + case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break; + default: + throw new RuntimeException("unexpected result"); + case Result.NO_EVALUATIONS_FOUND: // do nothing + } + } + rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION; + } + } + + /** + * + * @return a constant from the local Result class denoting whether there were any evaluation + * cases, and whether they all succeeded. + */ + private int processFunctionRow(HSSFFormulaEvaluator evaluator, String targetFunctionName, + HSSFRow formulasRow, HSSFRow expectedValuesRow) { + + int result = Result.NO_EVALUATIONS_FOUND; // so far + short endcolnum = formulasRow.getLastCellNum(); + evaluator.setCurrentRow(formulasRow); + + // iterate across the row for all the evaluation cases + for (short colnum=SS.COLUMN_INDEX_FIRST_TEST_VALUE; colnum < endcolnum; colnum++) { + HSSFCell c = formulasRow.getCell(colnum); + if (c == null || c.getCellType() != HSSFCell.CELL_TYPE_FORMULA) { + continue; + } + + HSSFFormulaEvaluator.CellValue actualValue = evaluator.evaluate(c); + + HSSFCell expectedValueCell = getExpectedValueCell(expectedValuesRow, colnum); + try { + confirmExpectedResult("Function '" + targetFunctionName + "': Formula: " + c.getCellFormula() + " @ " + formulasRow.getRowNum() + ":" + colnum, + expectedValueCell, actualValue); + _evaluationSuccessCount ++; + if(result != Result.SOME_EVALUATIONS_FAILED) { + result = Result.ALL_EVALUATIONS_SUCCEEDED; + } + } catch (AssertionFailedError e) { + _evaluationFailureCount ++; + printShortStackTrace(System.err, e); + result = Result.SOME_EVALUATIONS_FAILED; + } + } + return result; + } + + /** + * Useful to keep output concise when expecting many failures to be reported by this test case + */ + private static void printShortStackTrace(PrintStream ps, AssertionFailedError e) { + StackTraceElement[] stes = e.getStackTrace(); + + int startIx = 0; + // skip any top frames inside junit.framework.Assert + while(startIx= endIx) { + // something went wrong. just print the whole stack trace + e.printStackTrace(ps); + } + endIx -= 4; // skip 4 frames of reflection invocation + ps.println(e.toString()); + for(int i=startIx; inull if cell is missing, empty or blank + */ + private static String getTargetFunctionName(HSSFRow r) { + if(r == null) { + System.err.println("Warning - given null row, can't figure out function name"); + return null; + } + HSSFCell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME); + if(cell == null) { + System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name"); + return null; + } + if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) { + return null; + } + if(cell.getCellType() == HSSFCell.CELL_TYPE_STRING) { + return cell.getRichStringCellValue().getString(); + } + + throw new AssertionFailedError("Bad cell type for 'function name' column: (" + + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")"); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java new file mode 100755 index 0000000000..be8cef13fa --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestPercentEval.java @@ -0,0 +1,82 @@ +/* ==================================================================== + 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 junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.PercentPtg; +import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker; +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; + +/** + * Test for percent operator evaluator. + * + * @author Josh Micich + */ +public final class TestPercentEval extends TestCase { + + private static void confirm(ValueEval arg, double expectedResult) { + Eval[] args = { + arg, + }; + + PercentEval opEval = new PercentEval(new PercentPtg()); + double result = NumericFunctionInvoker.invoke(opEval, args, -1, (short)-1); + + assertEquals(expectedResult, result, 0); + } + + public void testBasic() { + confirm(new NumberEval(5), 0.05); + confirm(new NumberEval(3000), 30.0); + confirm(new NumberEval(-150), -1.5); + confirm(new StringEval("0.2"), 0.002); + confirm(BoolEval.TRUE, 0.01); + } + + public void testInSpreadSheet() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet("Sheet1"); + HSSFRow row = sheet.createRow(0); + HSSFCell cell = row.createCell((short)0); + cell.setCellFormula("B1%"); + row.createCell((short)1).setCellValue(50.0); + + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + fe.setCurrentRow(row); + CellValue cv; + try { + cv = fe.evaluate(cell); + } catch (RuntimeException e) { + if(e.getCause() instanceof NullPointerException) { + throw new AssertionFailedError("Identified bug 44608"); + } + // else some other unexpected error + throw e; + } + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType()); + assertEquals(0.5, cv.getNumberValue(), 0.0); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java new file mode 100755 index 0000000000..724c54cd90 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/eval/TestUnaryPlusEval.java @@ -0,0 +1,61 @@ +/* +* 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.AreaPtg; +import org.apache.poi.hssf.record.formula.UnaryPlusPtg; +import org.apache.poi.hssf.record.formula.functions.NumericFunctionInvoker; + +import junit.framework.TestCase; + +/** + * Test for unary plus operator evaluator. + * + * @author Josh Micich + */ +public final class TestUnaryPlusEval extends TestCase { + + /** + * Test for bug observable at svn revision 618865 (5-Feb-2008)
    + * The code for handling column operands had been copy-pasted from the row handling code. + */ + public void testColumnOperand() { + + short firstRow = (short)8; + short lastRow = (short)12; + short colNum = (short)5; + AreaPtg areaPtg = new AreaPtg(firstRow, lastRow, colNum, colNum, false, false, false, false); + ValueEval[] values = { + new NumberEval(27), + new NumberEval(29), + new NumberEval(35), // value in row 10 + new NumberEval(37), + new NumberEval(38), + }; + Eval areaEval = new Area2DEval(areaPtg, values); + Eval[] args = { + areaEval, + }; + + double result = NumericFunctionInvoker.invoke(new UnaryPlusEval(new UnaryPlusPtg()), args, 10, (short)20); + + assertEquals(35, result, 0); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/AbstractNumericTestCase.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/AbstractNumericTestCase.java new file mode 100644 index 0000000000..ef5b3add07 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/AbstractNumericTestCase.java @@ -0,0 +1,73 @@ +/* +* 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 29, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + +import junit.framework.TestCase; + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public abstract class AbstractNumericTestCase extends TestCase { + + public static final double POS_ZERO = 1E-4; + public static final double DIFF_TOLERANCE_FACTOR = 1E-8; + + public void setUp() { + } + + public void tearDown() { + } + + /** + * Why doesnt JUnit have a method like this for doubles? + * The current impl (3.8.1) of Junit has a retar*** method + * for comparing doubles. DO NOT use that. + * TODO: This class should really be in an abstract super class + * to avoid code duplication across this project. + * @param message + * @param baseval + * @param checkval + */ + public static void assertEquals(String message, double baseval, double checkval, double almostZero, double diffToleranceFactor) { + double posZero = Math.abs(almostZero); + double negZero = -1 * posZero; + if (Double.isNaN(baseval)) { + assertTrue(message+": Expected " + baseval + " but was " + checkval + , Double.isNaN(baseval)); + } + else if (Double.isInfinite(baseval)) { + assertTrue(message+": Expected " + baseval + " but was " + checkval + , Double.isInfinite(baseval) && ((baseval<0) == (checkval<0))); + } + else { + assertTrue(message+": Expected " + baseval + " but was " + checkval + ,baseval != 0 + ? Math.abs(baseval - checkval) <= Math.abs(diffToleranceFactor * baseval) + : checkval < posZero && checkval > negZero); + } + } + + public static void assertEquals(String msg, double baseval, double checkval) { + assertEquals(msg, baseval, checkval, POS_ZERO, DIFF_TOLERANCE_FACTOR); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/AllIndividualFunctionEvaluationTests.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/AllIndividualFunctionEvaluationTests.java new file mode 100755 index 0000000000..66d2a1d270 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/AllIndividualFunctionEvaluationTests.java @@ -0,0 +1,53 @@ +/* ==================================================================== + 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 junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Direct tests for all implementors of Function. + * + * @author Josh Micich + */ +public final class AllIndividualFunctionEvaluationTests { + + // TODO - have this suite incorporated into a higher level one + public static Test suite() { + TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.functions"); + result.addTestSuite(TestAverage.class); + result.addTestSuite(TestCountFuncs.class); + result.addTestSuite(TestDate.class); + result.addTestSuite(TestFinanceLib.class); + result.addTestSuite(TestIndex.class); + result.addTestSuite(TestIsBlank.class); + result.addTestSuite(TestLen.class); + result.addTestSuite(TestMid.class); + result.addTestSuite(TestMathX.class); + result.addTestSuite(TestMatch.class); + result.addTestSuite(TestPmt.class); + result.addTestSuite(TestOffset.class); + result.addTestSuite(TestRowCol.class); + result.addTestSuite(TestSumproduct.class); + result.addTestSuite(TestStatsLib.class); + result.addTestSuite(TestTFunc.class); + result.addTestSuite(TestTrim.class); + result.addTestSuite(TestXYNumericFunction.class); + return result; + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java new file mode 100755 index 0000000000..a6e262b868 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/EvalFactory.java @@ -0,0 +1,63 @@ +/* ==================================================================== + 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.AreaPtg; +import org.apache.poi.hssf.record.formula.ReferencePtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +import org.apache.poi.hssf.record.formula.eval.AreaEval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.Ref2DEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * Test helper class for creating mock Eval objects + * + * @author Josh Micich + */ +final class EvalFactory { + private static final NumberEval ZERO = new NumberEval(0); + + private EvalFactory() { + // no instances of this class + } + + /** + * Creates a dummy AreaEval (filled with zeros) + *

    + * nCols and nRows could have been derived + */ + public static AreaEval createAreaEval(String areaRefStr, int nCols, int nRows) { + int nValues = nCols * nRows; + ValueEval[] values = new ValueEval[nValues]; + for (int i = 0; i < nValues; i++) { + values[i] = ZERO; + } + + return new Area2DEval(new AreaPtg(areaRefStr), values); + } + + /** + * Creates a single RefEval (with value zero) + */ + public static RefEval createRefEval(String refStr) { + return new Ref2DEval(new ReferencePtg(refStr), ZERO); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java new file mode 100755 index 0000000000..d477231349 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/NumericFunctionInvoker.java @@ -0,0 +1,126 @@ +/* ==================================================================== + 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 junit.framework.AssertionFailedError; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.OperationEval; + +/** + * Test helper class for invoking functions with numeric results. + * + * @author Josh Micich + */ +public final class NumericFunctionInvoker { + + private NumericFunctionInvoker() { + // no instances of this class + } + + private static final class NumericEvalEx extends Exception { + public NumericEvalEx(String msg) { + super(msg); + } + } + + /** + * Invokes the specified function with the arguments. + *

    + * Assumes that the cell coordinate parameters of + * Function.evaluate(args, srcCellRow, srcCellCol) + * are not required. + *

    + * This method cannot be used for confirming error return codes. Any non-numeric evaluation + * result causes the current junit test to fail. + */ + public static double invoke(Function f, Eval[] args) { + try { + return invokeInternal(f, args, -1, -1); + } catch (NumericEvalEx e) { + throw new AssertionFailedError("Evaluation of function (" + f.getClass().getName() + + ") failed: " + e.getMessage()); + } + + } + /** + * Invokes the specified operator with the arguments. + *

    + * This method cannot be used for confirming error return codes. Any non-numeric evaluation + * result causes the current junit test to fail. + */ + public static double invoke(OperationEval f, Eval[] args, int srcCellRow, int srcCellCol) { + try { + return invokeInternal(f, args, srcCellRow, srcCellCol); + } catch (NumericEvalEx e) { + throw new AssertionFailedError("Evaluation of function (" + f.getClass().getName() + + ") failed: " + e.getMessage()); + } + + } + /** + * Formats nicer error messages for the junit output + */ + private static double invokeInternal(Object target, Eval[] args, int srcCellRow, int srcCellCol) + throws NumericEvalEx { + Eval evalResult; + // TODO - make OperationEval extend Function + if (target instanceof Function) { + Function ff = (Function) target; + evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol); + } else { + OperationEval ff = (OperationEval) target; + evalResult = ff.evaluate(args, srcCellRow, (short)srcCellCol); + } + + if(evalResult == null) { + throw new NumericEvalEx("Result object was null"); + } + if(evalResult instanceof ErrorEval) { + ErrorEval ee = (ErrorEval) evalResult; + throw new NumericEvalEx(formatErrorMessage(ee)); + } + if(!(evalResult instanceof NumericValueEval)) { + throw new NumericEvalEx("Result object type (" + evalResult.getClass().getName() + + ") is invalid. Expected implementor of (" + + NumericValueEval.class.getName() + ")"); + } + + NumericValueEval result = (NumericValueEval) evalResult; + return result.getNumberValue(); + } + private static String formatErrorMessage(ErrorEval ee) { + if(errorCodesAreEqual(ee, ErrorEval.FUNCTION_NOT_IMPLEMENTED)) { + return "Function not implemented"; + } + if(errorCodesAreEqual(ee, ErrorEval.VALUE_INVALID)) { + return "Error code: #VALUE! (invalid value)"; + } + return "Error code=" + ee.getErrorCode(); + } + private static boolean errorCodesAreEqual(ErrorEval a, ErrorEval b) { + if(a==b) { + return true; + } + return a.getErrorCode() == b.getErrorCode(); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java new file mode 100755 index 0000000000..4f0e5fff2c --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestAverage.java @@ -0,0 +1,103 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +/** + * Tests for Excel function AVERAGE() + * + * @author Josh Micich + */ +public final class TestAverage extends TestCase { + + + private static Eval invokeAverage(Eval[] args) { + return new Average().evaluate(args, -1, (short)-1); + } + + private void confirmAverage(Eval[] args, double expected) { + Eval result = invokeAverage(args); + assertEquals(NumberEval.class, result.getClass()); + assertEquals(expected, ((NumberEval)result).getNumberValue(), 0); + } + + private void confirmAverage(Eval[] args, ErrorEval expectedError) { + Eval result = invokeAverage(args); + assertEquals(ErrorEval.class, result.getClass()); + assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); + } + + public void testBasic() { + + ValueEval[] values = { + new NumberEval(1), + new NumberEval(2), + new NumberEval(3), + new NumberEval(4), + }; + + confirmAverage(values, 2.5); + + values = new ValueEval[] { + new NumberEval(1), + new NumberEval(2), + BlankEval.INSTANCE, + new NumberEval(3), + BlankEval.INSTANCE, + new NumberEval(4), + BlankEval.INSTANCE, + }; + + confirmAverage(values, 2.5); + } + + /** + * Valid cases where values are not pure numbers + */ + public void testUnusualArgs() { + ValueEval[] values = { + new NumberEval(1), + new NumberEval(2), + BoolEval.TRUE, + BoolEval.FALSE, + }; + + confirmAverage(values, 1.0); + + } + + // currently disabled because MultiOperandNumericFunction.getNumberArray(Eval[], int, short) + // does not handle error values properly yet + public void XtestErrors() { + ValueEval[] values = { + new NumberEval(1), + ErrorEval.NAME_INVALID, + new NumberEval(3), + ErrorEval.DIV_ZERO, + }; + confirmAverage(values, ErrorEval.NAME_INVALID); + + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java new file mode 100755 index 0000000000..ae93a2d41b --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java @@ -0,0 +1,150 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.hssf.record.formula.ReferencePtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.Ref2DEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * Test cases for COUNT(), COUNTA() COUNTIF(), COUNTBLANK() + * + * @author Josh Micich + */ +public final class TestCountFuncs extends TestCase { + + public TestCountFuncs(String testName) { + super(testName); + } + + public void testCountA() { + + Eval[] args; + + args = new Eval[] { + new NumberEval(0), + }; + confirmCountA(1, args); + + args = new Eval[] { + new NumberEval(0), + new NumberEval(0), + new StringEval(""), + }; + confirmCountA(3, args); + + args = new Eval[] { + EvalFactory.createAreaEval("D2:F5", 3, 4), + }; + confirmCountA(12, args); + + args = new Eval[] { + EvalFactory.createAreaEval("D1:F5", 3, 5), // 15 + EvalFactory.createRefEval("A1"), + EvalFactory.createAreaEval("A1:F6", 7, 6), // 42 + new NumberEval(0), + }; + confirmCountA(59, args); + } + + public void testCountIf() { + + AreaEval range; + ValueEval[] values; + + // when criteria is a boolean value + values = new ValueEval[] { + new NumberEval(0), + new StringEval("TRUE"), // note - does not match boolean TRUE + BoolEval.TRUE, + BoolEval.FALSE, + BoolEval.TRUE, + BlankEval.INSTANCE, + }; + range = createAreaEval("A1:B2", values); + confirmCountIf(2, range, BoolEval.TRUE); + + // when criteria is numeric + values = new ValueEval[] { + new NumberEval(0), + new StringEval("2"), + new StringEval("2.001"), + new NumberEval(2), + new NumberEval(2), + BoolEval.TRUE, + BlankEval.INSTANCE, + }; + range = createAreaEval("A1:B2", values); + confirmCountIf(3, range, new NumberEval(2)); + // note - same results when criteria is a string that parses as the number with the same value + confirmCountIf(3, range, new StringEval("2.00")); + + if (false) { // not supported yet: + // when criteria is an expression (starting with a comparison operator) + confirmCountIf(4, range, new StringEval(">1")); + } + } + /** + * special case where the criteria argument is a cell reference + */ + public void testCountIfWithCriteriaReference() { + + ValueEval[] values = { + new NumberEval(22), + new NumberEval(25), + new NumberEval(21), + new NumberEval(25), + new NumberEval(25), + new NumberEval(25), + }; + Area2DEval arg0 = new Area2DEval(new AreaPtg("C1:C6"), values); + + Ref2DEval criteriaArg = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(25)); + Eval[] args= { arg0, criteriaArg, }; + + double actual = NumericFunctionInvoker.invoke(new Countif(), args); + assertEquals(4, actual, 0D); + } + + + private static AreaEval createAreaEval(String areaRefStr, ValueEval[] values) { + return new Area2DEval(new AreaPtg(areaRefStr), values); + } + + private static void confirmCountA(int expected, Eval[] args) { + double result = NumericFunctionInvoker.invoke(new Counta(), args); + assertEquals(expected, result, 0); + } + private static void confirmCountIf(int expected, AreaEval range, Eval criteria) { + + Eval[] args = { range, criteria, }; + double result = NumericFunctionInvoker.invoke(new Countif(), args); + assertEquals(expected, result, 0); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestDate.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestDate.java new file mode 100644 index 0000000000..2c5e152ab8 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestDate.java @@ -0,0 +1,100 @@ +/* + * Created on Sep 11, 2007 + * + * The Copyright statements and Licenses for the commons application may be + * found in the file LICENSE.txt + */ + +package org.apache.poi.hssf.record.formula.functions; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; + +/** + * @author Pavel Krupets (pkrupets at palmtreebusiness dot com) + */ +public class TestDate extends TestCase { + public void setUp() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet("new sheet"); + HSSFRow row1 = sheet.createRow((short) 0); + + this.cell11 = row1.createCell((short) 0); + + this.evaluator = new HSSFFormulaEvaluator(sheet, wb); + this.evaluator.setCurrentRow(row1); + } + + /** + * Test disabled pending a fix in the formula parser + */ + public void DISABLEDtestSomeArgumentsMissing() throws Exception { + this.cell11.setCellFormula("DATE(, 1, 0)"); + assertEquals(0.0, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(, 1, 1)"); + assertEquals(1.0, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + } + + public void testValid() throws Exception { + this.cell11.setCellType(HSSFCell.CELL_TYPE_FORMULA); + + this.cell11.setCellFormula("DATE(1900, 1, 1)"); + assertEquals(1, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1900, 1, 32)"); + assertEquals(32, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1900, 222, 1)"); + assertEquals(6727, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1900, 2, 0)"); + assertEquals(31, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(2000, 1, 222)"); + assertEquals(36747.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(2007, 1, 1)"); + assertEquals(39083, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + } + + public void testBugDate() { + this.cell11.setCellFormula("DATE(1900, 2, 29)"); + assertEquals(60, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1900, 2, 30)"); + assertEquals(61, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1900, 1, 222)"); + assertEquals(222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1900, 1, 2222)"); + assertEquals(2222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1900, 1, 22222)"); + assertEquals(22222, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + } + + public void testPartYears() { + this.cell11.setCellFormula("DATE(4, 1, 1)"); + assertEquals(1462.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(14, 1, 1)"); + assertEquals(5115.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(104, 1, 1)"); + assertEquals(37987.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + + this.cell11.setCellFormula("DATE(1004, 1, 1)"); + assertEquals(366705.00, this.evaluator.evaluate(this.cell11).getNumberValue(), 0); + } + + private HSSFCell cell11; + private HSSFFormulaEvaluator evaluator; +} + diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestFinanceLib.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestFinanceLib.java new file mode 100644 index 0000000000..4dfe1fbb52 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestFinanceLib.java @@ -0,0 +1,202 @@ +/* +* 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 23, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class TestFinanceLib extends AbstractNumericTestCase { + + public void testFv() { + double f, r, y, p, x; + int n; + boolean t = false; + + r = 0; n = 3; y = 2; p = 7; t = true; + f = FinanceLib.fv(r, n, y, p, t); + x = -13; + assertEquals("fv ", x, f); + + r = 1; n = 10; y = 100; p = 10000; t = false; + f = FinanceLib.fv(r, n, y, p, t); + x = -10342300; + assertEquals("fv ", x, f); + + r = 1; n = 10; y = 100; p = 10000; t = true; + f = FinanceLib.fv(r, n, y, p, t); + x = -10444600; + assertEquals("fv ", x, f); + + r = 2; n = 12; y = 120; p = 12000; t = false; + f = FinanceLib.fv(r, n, y, p, t); + x = -6409178400d; + assertEquals("fv ", x, f); + + r = 2; n = 12; y = 120; p = 12000; t = true; + f = FinanceLib.fv(r, n, y, p, t); + x = -6472951200d; + assertEquals("fv ", x, f); + + // cross tests with pv + r = 2.95; n = 13; y = 13000; p = -4406.78544294496; t = false; + f = FinanceLib.fv(r, n, y, p, t); + x = 333891.230010986; // as returned by excel + assertEquals("fv ", x, f); + + r = 2.95; n = 13; y = 13000; p = -17406.7852148156; t = true; + f = FinanceLib.fv(r, n, y, p, t); + x = 333891.230102539; // as returned by excel + assertEquals("fv ", x, f); + + } + public void testNpv() { + double r, v[], npv, x; + + r = 1; v = new double[]{100, 200, 300, 400}; + npv = FinanceLib.npv(r, v); + x = 162.5; + assertEquals("npv ", x, npv); + + r = 2.5; v = new double[]{1000, 666.66666, 333.33, 12.2768416}; + npv = FinanceLib.npv(r, v); + x = 347.99232604144827; + assertEquals("npv ", x, npv); + + r = 12.33333; v = new double[]{1000, 0, -900, -7777.5765}; + npv = FinanceLib.npv(r, v); + x = 74.3742433377061; + assertEquals("npv ", x, npv); + + r = 0.05; v = new double[]{200000, 300000.55, 400000, 1000000, 6000000, 7000000, -300000}; + npv = FinanceLib.npv(r, v); + x = 11342283.4233124; + assertEquals("npv ", x, npv); + } + public void testPmt() { + double f, r, y, p, x; + int n; + boolean t = false; + + r = 0; n = 3; p = 2; f = 7; t = true; + y = FinanceLib.pmt(r, n, p, f, t); + x = -3; + assertEquals("pmt ", x, y); + + // cross check with pv + r = 1; n = 10; p = -109.66796875; f = 10000; t = false; + y = FinanceLib.pmt(r, n, p, f, t); + x = 100; + assertEquals("pmt ", x, y); + + r = 1; n = 10; p = -209.5703125; f = 10000; t = true; + y = FinanceLib.pmt(r, n, p, f, t); + x = 100; + assertEquals("pmt ", x, y); + + // cross check with fv + r = 2; n = 12; f = -6409178400d; p = 12000; t = false; + y = FinanceLib.pmt(r, n, p, f, t); + x = 120; + assertEquals("pmt ", x, y); + + r = 2; n = 12; f = -6472951200d; p = 12000; t = true; + y = FinanceLib.pmt(r, n, p, f, t); + x = 120; + assertEquals("pmt ", x, y); + } + + public void testPv() { + double f, r, y, p, x; + int n; + boolean t = false; + + r = 0; n = 3; y = 2; f = 7; t = true; + f = FinanceLib.pv(r, n, y, f, t); + x = -13; + assertEquals("pv ", x, f); + + r = 1; n = 10; y = 100; f = 10000; t = false; + p = FinanceLib.pv(r, n, y, f, t); + x = -109.66796875; + assertEquals("pv ", x, p); + + r = 1; n = 10; y = 100; f = 10000; t = true; + p = FinanceLib.pv(r, n, y, f, t); + x = -209.5703125; + assertEquals("pv ", x, p); + + r = 2.95; n = 13; y = 13000; f = 333891.23; t = false; + p = FinanceLib.pv(r, n, y, f, t); + x = -4406.78544294496; + assertEquals("pv ", x, p); + + r = 2.95; n = 13; y = 13000; f = 333891.23; t = true; + p = FinanceLib.pv(r, n, y, f, t); + x = -17406.7852148156; + assertEquals("pv ", x, p); + + // cross tests with fv + r = 2; n = 12; y = 120; f = -6409178400d; t = false; + p = FinanceLib.pv(r, n, y, f, t); + x = 12000; + assertEquals("pv ", x, p); + + r = 2; n = 12; y = 120; f = -6472951200d; t = true; + p = FinanceLib.pv(r, n, y, f, t); + x = 12000; + assertEquals("pv ", x, p); + + } + + public void testNper() { + double f, r, y, p, x, n; + boolean t = false; + + r = 0; y = 7; p = 2; f = 3; t = false; + n = FinanceLib.nper(r, y, p, f, t); + x = -0.71428571429; // can you believe it? excel returns nper as a fraction!?? + assertEquals("nper ", x, n); + + // cross check with pv + r = 1; y = 100; p = -109.66796875; f = 10000; t = false; + n = FinanceLib.nper(r, y, p, f, t); + x = 10; + assertEquals("nper ", x, n); + + r = 1; y = 100; p = -209.5703125; f = 10000; t = true; + n = FinanceLib.nper(r, y, p, f, t); + x = 10; + assertEquals("nper ", x, n); + + // cross check with fv + r = 2; y = 120; f = -6409178400d; p = 12000; t = false; + n = FinanceLib.nper(r, y, p, f, t); + x = 12; + assertEquals("nper ", x, n); + + r = 2; y = 120; f = -6472951200d; p = 12000; t = true; + n = FinanceLib.nper(r, y, p, f, t); + x = 12; + assertEquals("nper ", x, n); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java new file mode 100755 index 0000000000..902c4122ef --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIndex.java @@ -0,0 +1,89 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * Tests for the INDEX() function + * + * @author Josh Micich + */ +public final class TestIndex extends TestCase { + + public TestIndex(String testName) { + super(testName); + } + + private static final double[] TEST_VALUES0 = { + 1, 2, + 3, 4, + 5, 6, + 7, 8, + 9, 10, + 11, 12, + 13, // excess array element. TODO - Area2DEval currently has no validation to ensure correct size of values array + }; + + /** + * For the case when the first argument to INDEX() is an area reference + */ + public void testEvaluateAreaReference() { + + double[] values = TEST_VALUES0; + confirmAreaEval("C1:D6", values, 4, 1, 7); + confirmAreaEval("C1:D6", values, 6, 2, 12); + confirmAreaEval("C1:D6", values, 3, -1, 5); + + // now treat same data as 3 columns, 4 rows + confirmAreaEval("C10:E13", values, 2, 2, 5); + confirmAreaEval("C10:E13", values, 4, -1, 10); + } + + /** + * @param areaRefString in Excel notation e.g. 'D2:E97' + * @param dValues array of evaluated values for the area reference + * @param rowNum 1-based + * @param colNum 1-based, pass -1 to signify argument not present + */ + private static void confirmAreaEval(String areaRefString, double[] dValues, + int rowNum, int colNum, double expectedResult) { + ValueEval[] values = new ValueEval[dValues.length]; + for (int i = 0; i < values.length; i++) { + values[i] = new NumberEval(dValues[i]); + } + Area2DEval arg0 = new Area2DEval(new AreaPtg(areaRefString), values); + + Eval[] args; + if (colNum > 0) { + args = new Eval[] { arg0, new NumberEval(rowNum), new NumberEval(colNum), }; + } else { + args = new Eval[] { arg0, new NumberEval(rowNum), }; + } + + double actual = NumericFunctionInvoker.invoke(new Index(), args); + assertEquals(expectedResult, actual, 0D); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIsBlank.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIsBlank.java new file mode 100755 index 0000000000..7ce2bd245b --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestIsBlank.java @@ -0,0 +1,62 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; +/** + * Tests for Excel function ISBLANK() + * + * @author Josh Micich + */ +public final class TestIsBlank extends TestCase { + + + + public void test3DArea() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet1 = wb.createSheet(); + wb.setSheetName(0, "Sheet1"); + wb.createSheet(); + wb.setSheetName(1, "Sheet2"); + HSSFRow row = sheet1.createRow(0); + HSSFCell cell = row.createCell((short)0); + + + cell.setCellFormula("isblank(Sheet2!A1:A1)"); + + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb); + fe.setCurrentRow(row); + CellValue result = fe.evaluate(cell); + assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType()); + assertEquals(true, result.getBooleanValue()); + + cell.setCellFormula("isblank(D7:D7)"); + + result = fe.evaluate(cell); + assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType()); + assertEquals(true, result.getBooleanValue()); + + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestLen.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestLen.java new file mode 100755 index 0000000000..a96fb4e2b0 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestLen.java @@ -0,0 +1,73 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +/** + * Tests for Excel function LEN() + * + * @author Josh Micich + */ +public final class TestLen extends TestCase { + + + private static Eval invokeLen(Eval text) { + Eval[] args = new Eval[] { text, }; + return new Len().evaluate(args, -1, (short)-1); + } + + private void confirmLen(Eval text, int expected) { + Eval result = invokeLen(text); + assertEquals(NumberEval.class, result.getClass()); + assertEquals(expected, ((NumberEval)result).getNumberValue(), 0); + } + + private void confirmLen(Eval text, ErrorEval expectedError) { + Eval result = invokeLen(text); + assertEquals(ErrorEval.class, result.getClass()); + assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); + } + + public void testBasic() { + + confirmLen(new StringEval("galactic"), 8); + } + + /** + * Valid cases where text arg is not exactly a string + */ + public void testUnusualArgs() { + + // text (first) arg type is number, other args are strings with fractional digits + confirmLen(new NumberEval(123456), 6); + confirmLen(BoolEval.FALSE, 5); + confirmLen(BoolEval.TRUE, 4); + confirmLen(BlankEval.INSTANCE, 0); + } + + public void testErrors() { + confirmLen(ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestLookupFunctionsFromSpreadsheet.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestLookupFunctionsFromSpreadsheet.java new file mode 100644 index 0000000000..071ca0f7d8 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestLookupFunctionsFromSpreadsheet.java @@ -0,0 +1,385 @@ +/* +* 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.io.FileInputStream; +import java.io.IOException; +import java.io.PrintStream; + +import junit.framework.Assert; +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; +import org.apache.poi.hssf.util.CellReference; + +/** + * Tests lookup functions (VLOOKUP, HLOOKUP, LOOKUP, MATCH) as loaded from a test data spreadsheet.

    + * These tests have been separated from the common function and operator tests because the lookup + * functions have more complex test cases and test data setup. + * + * Tests for bug fixes and specific/tricky behaviour can be found in the corresponding test class + * (TestXxxx) of the target (Xxxx) implementor, where execution can be observed + * more easily. + * + * @author Josh Micich + */ +public final class TestLookupFunctionsFromSpreadsheet extends TestCase { + + private static final class Result { + public static final int SOME_EVALUATIONS_FAILED = -1; + public static final int ALL_EVALUATIONS_SUCCEEDED = +1; + public static final int NO_EVALUATIONS_FOUND = 0; + } + + /** + * This class defines constants for navigating around the test data spreadsheet used for these tests. + */ + private static final class SS { + + /** Name of the test spreadsheet (found in the standard test data folder) */ + public final static String FILENAME = "LookupFunctionsTestCaseData.xls"; + + /** Name of the first sheet in the spreadsheet (contains comments) */ + public final static String README_SHEET_NAME = "Read Me"; + + + /** Row (zero-based) in each sheet where the evaluation cases start. */ + public static final int START_TEST_CASES_ROW_INDEX = 4; // Row '5' + /** Index of the column that contains the function names */ + public static final short COLUMN_INDEX_MARKER = 0; // Column 'A' + public static final short COLUMN_INDEX_EVALUATION = 1; // Column 'B' + public static final short COLUMN_INDEX_EXPECTED_RESULT = 2; // Column 'C' + public static final short COLUMN_ROW_COMMENT = 3; // Column 'D' + + /** Used to indicate when there are no more test cases on the current sheet */ + public static final String TEST_CASES_END_MARKER = ""; + /** Used to indicate that the test on the current row should be ignored */ + public static final String SKIP_CURRENT_TEST_CASE_MARKER = ""; + + } + + // Note - multiple failures are aggregated before ending. + // If one or more functions fail, a single AssertionFailedError is thrown at the end + private int _sheetFailureCount; + private int _sheetSuccessCount; + private int _evaluationFailureCount; + private int _evaluationSuccessCount; + + + + private static void confirmExpectedResult(String msg, HSSFCell expected, HSSFFormulaEvaluator.CellValue actual) { + if (expected == null) { + throw new AssertionFailedError(msg + " - Bad setup data expected value is null"); + } + if(actual == null) { + throw new AssertionFailedError(msg + " - actual value was null"); + } + if(expected.getCellType() == HSSFCell.CELL_TYPE_ERROR) { + confirmErrorResult(msg, expected.getErrorCellValue(), actual); + return; + } + if(actual.getCellType() == HSSFCell.CELL_TYPE_ERROR) { + throw unexpectedError(msg, expected, actual.getErrorValue()); + } + if(actual.getCellType() != expected.getCellType()) { + throw wrongTypeError(msg, expected, actual); + } + + + switch (expected.getCellType()) { + case HSSFCell.CELL_TYPE_BOOLEAN: + assertEquals(msg, expected.getBooleanCellValue(), actual.getBooleanValue()); + break; + case HSSFCell.CELL_TYPE_FORMULA: // will never be used, since we will call method after formula evaluation + throw new AssertionFailedError("Cannot expect formula as result of formula evaluation: " + msg); + case HSSFCell.CELL_TYPE_NUMERIC: + assertEquals(expected.getNumericCellValue(), actual.getNumberValue(), 0.0); + break; + case HSSFCell.CELL_TYPE_STRING: + assertEquals(msg, expected.getRichStringCellValue().getString(), actual.getRichTextStringValue().getString()); + break; + } + } + + + private static AssertionFailedError wrongTypeError(String msgPrefix, HSSFCell expectedCell, CellValue actualValue) { + return new AssertionFailedError(msgPrefix + " Result type mismatch. Evaluated result was " + + formatValue(actualValue) + + " but the expected result was " + + formatValue(expectedCell) + ); + } + private static AssertionFailedError unexpectedError(String msgPrefix, HSSFCell expected, int actualErrorCode) { + return new AssertionFailedError(msgPrefix + " Error code (" + + ErrorEval.getText(actualErrorCode) + + ") was evaluated, but the expected result was " + + formatValue(expected) + ); + } + + + private static void confirmErrorResult(String msgPrefix, int expectedErrorCode, CellValue actual) { + if(actual.getCellType() != HSSFCell.CELL_TYPE_ERROR) { + throw new AssertionFailedError(msgPrefix + " Expected cell error (" + + ErrorEval.getText(expectedErrorCode) + ") but actual value was " + + formatValue(actual)); + } + if(expectedErrorCode != actual.getErrorValue()) { + throw new AssertionFailedError(msgPrefix + " Expected cell error code (" + + ErrorEval.getText(expectedErrorCode) + + ") but actual error code was (" + + ErrorEval.getText(actual.getErrorValue()) + + ")"); + } + } + + + private static String formatValue(HSSFCell expecedCell) { + switch (expecedCell.getCellType()) { + case HSSFCell.CELL_TYPE_BLANK: return ""; + case HSSFCell.CELL_TYPE_BOOLEAN: return String.valueOf(expecedCell.getBooleanCellValue()); + case HSSFCell.CELL_TYPE_NUMERIC: return String.valueOf(expecedCell.getNumericCellValue()); + case HSSFCell.CELL_TYPE_STRING: return expecedCell.getRichStringCellValue().getString(); + } + throw new RuntimeException("Unexpected cell type of expected value (" + expecedCell.getCellType() + ")"); + } + private static String formatValue(CellValue actual) { + switch (actual.getCellType()) { + case HSSFCell.CELL_TYPE_BLANK: return ""; + case HSSFCell.CELL_TYPE_BOOLEAN: return String.valueOf(actual.getBooleanValue()); + case HSSFCell.CELL_TYPE_NUMERIC: return String.valueOf(actual.getNumberValue()); + case HSSFCell.CELL_TYPE_STRING: return actual.getRichTextStringValue().getString(); + } + throw new RuntimeException("Unexpected cell type of evaluated value (" + actual.getCellType() + ")"); + } + + + protected void setUp() throws Exception { + _sheetFailureCount = 0; + _sheetSuccessCount = 0; + _evaluationFailureCount = 0; + _evaluationSuccessCount = 0; + } + + public void testFunctionsFromTestSpreadsheet() { + String filePath = System.getProperty("HSSF.testdata.path")+ "/" + SS.FILENAME; + HSSFWorkbook workbook; + try { + FileInputStream fin = new FileInputStream( filePath ); + workbook = new HSSFWorkbook( fin ); + } catch (IOException e) { + throw new RuntimeException(e); + } + + confirmReadMeSheet(workbook); + int nSheets = workbook.getNumberOfSheets(); + for(int i=1; i< nSheets; i++) { + int sheetResult = processTestSheet(workbook, i, workbook.getSheetName(i)); + switch(sheetResult) { + case Result.ALL_EVALUATIONS_SUCCEEDED: _sheetSuccessCount ++; break; + case Result.SOME_EVALUATIONS_FAILED: _sheetFailureCount ++; break; + } + } + + // confirm results + String successMsg = "There were " + + _sheetSuccessCount + " successful sheets(s) and " + + _evaluationSuccessCount + " function(s) without error"; + if(_sheetFailureCount > 0) { + String msg = _sheetFailureCount + " sheets(s) failed with " + + _evaluationFailureCount + " evaluation(s). " + successMsg; + throw new AssertionFailedError(msg); + } + if(false) { // normally no output for successful tests + System.out.println(getClass().getName() + ": " + successMsg); + } + } + + private int processTestSheet(HSSFWorkbook workbook, int sheetIndex, String sheetName) { + HSSFSheet sheet = workbook.getSheetAt(sheetIndex); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook); + int maxRows = sheet.getLastRowNum()+1; + int result = Result.NO_EVALUATIONS_FOUND; // so far + + String currentGroupComment = null; + for(int rowIndex=SS.START_TEST_CASES_ROW_INDEX; rowIndex= endIx) { + // something went wrong. just print the whole stack trace + e.printStackTrace(ps); + } + endIx -= 4; // skip 4 frames of reflection invocation + ps.println(e.toString()); + for(int i=startIx; inull if cell is missing, empty or blank + */ + private static String getCellTextValue(HSSFRow r, int colIndex, String columnName) { + if(r == null) { + return null; + } + HSSFCell cell = r.getCell((short) colIndex); + if(cell == null) { + return null; + } + if(cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) { + return null; + } + if(cell.getCellType() == HSSFCell.CELL_TYPE_STRING) { + return cell.getRichStringCellValue().getString(); + } + + throw new RuntimeException("Bad cell type for '" + columnName + "' column: (" + + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")"); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMatch.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMatch.java new file mode 100755 index 0000000000..d275e5f333 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMatch.java @@ -0,0 +1,215 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +import org.apache.poi.hssf.record.formula.eval.AreaEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +/** + * Test cases for MATCH() + * + * @author Josh Micich + */ +public final class TestMatch extends TestCase { + /** less than or equal to */ + private static final NumberEval MATCH_LARGEST_LTE = new NumberEval(1); + private static final NumberEval MATCH_EXACT = new NumberEval(0); + /** greater than or equal to */ + private static final NumberEval MATCH_SMALLEST_GTE = new NumberEval(-1); + + + private static Eval invokeMatch(Eval lookup_value, Eval lookup_array, Eval match_type) { + Eval[] args = { lookup_value, lookup_array, match_type, }; + return new Match().evaluate(args, -1, (short)-1); + } + private static void confirmInt(int expected, Eval actualEval) { + if(!(actualEval instanceof NumericValueEval)) { + fail("Expected numeric result"); + } + NumericValueEval nve = (NumericValueEval)actualEval; + assertEquals(expected, nve.getNumberValue(), 0); + } + /** + * Convenience method + * @return new Area2DEval(new AreaPtg(ref), values) + */ + private static AreaEval createAreaEval(String ref, ValueEval[] values) { + return new Area2DEval(new AreaPtg(ref), values); + } + + public void testSimpleNumber() { + + ValueEval[] values = { + new NumberEval(4), + new NumberEval(5), + new NumberEval(10), + new NumberEval(10), + new NumberEval(25), + }; + + AreaEval ae = createAreaEval("A1:A5", values); + + confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE)); + confirmInt(2, invokeMatch(new NumberEval(5), ae, MATCH_EXACT)); + confirmInt(4, invokeMatch(new NumberEval(10), ae, MATCH_LARGEST_LTE)); + confirmInt(3, invokeMatch(new NumberEval(10), ae, MATCH_EXACT)); + confirmInt(4, invokeMatch(new NumberEval(20), ae, MATCH_LARGEST_LTE)); + assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(20), ae, MATCH_EXACT)); + } + + public void testReversedNumber() { + + ValueEval[] values = { + new NumberEval(25), + new NumberEval(10), + new NumberEval(10), + new NumberEval(10), + new NumberEval(4), + }; + + AreaEval ae = createAreaEval("A1:A5", values); + + confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_SMALLEST_GTE)); + confirmInt(2, invokeMatch(new NumberEval(10), ae, MATCH_EXACT)); + confirmInt(4, invokeMatch(new NumberEval(9), ae, MATCH_SMALLEST_GTE)); + confirmInt(1, invokeMatch(new NumberEval(20), ae, MATCH_SMALLEST_GTE)); + assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(20), ae, MATCH_EXACT)); + assertEquals(ErrorEval.NA, invokeMatch(new NumberEval(26), ae, MATCH_SMALLEST_GTE)); + } + + public void testSimpleString() { + + ValueEval[] values = { + new StringEval("Albert"), + new StringEval("Charles"), + new StringEval("Ed"), + new StringEval("Greg"), + new StringEval("Ian"), + }; + + AreaEval ae = createAreaEval("A1:A5", values); + + // Note String comparisons are case insensitive + confirmInt(3, invokeMatch(new StringEval("Ed"), ae, MATCH_LARGEST_LTE)); + confirmInt(3, invokeMatch(new StringEval("eD"), ae, MATCH_LARGEST_LTE)); + confirmInt(3, invokeMatch(new StringEval("Ed"), ae, MATCH_EXACT)); + confirmInt(3, invokeMatch(new StringEval("ed"), ae, MATCH_EXACT)); + confirmInt(4, invokeMatch(new StringEval("Hugh"), ae, MATCH_LARGEST_LTE)); + assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Hugh"), ae, MATCH_EXACT)); + } + + public void testSimpleBoolean() { + + ValueEval[] values = { + BoolEval.FALSE, + BoolEval.FALSE, + BoolEval.TRUE, + BoolEval.TRUE, + }; + + AreaEval ae = createAreaEval("A1:A4", values); + + // Note String comparisons are case insensitive + confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE)); + confirmInt(1, invokeMatch(BoolEval.FALSE, ae, MATCH_EXACT)); + confirmInt(4, invokeMatch(BoolEval.TRUE, ae, MATCH_LARGEST_LTE)); + confirmInt(3, invokeMatch(BoolEval.TRUE, ae, MATCH_EXACT)); + } + + public void testHeterogeneous() { + + ValueEval[] values = { + new NumberEval(4), + BoolEval.FALSE, + new NumberEval(5), + new StringEval("Albert"), + BoolEval.FALSE, + BoolEval.TRUE, + new NumberEval(10), + new StringEval("Charles"), + new StringEval("Ed"), + new NumberEval(10), + new NumberEval(25), + BoolEval.TRUE, + new StringEval("Ed"), + }; + + AreaEval ae = createAreaEval("A1:A13", values); + + assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Aaron"), ae, MATCH_LARGEST_LTE)); + + confirmInt(5, invokeMatch(BoolEval.FALSE, ae, MATCH_LARGEST_LTE)); + confirmInt(2, invokeMatch(BoolEval.FALSE, ae, MATCH_EXACT)); + confirmInt(3, invokeMatch(new NumberEval(5), ae, MATCH_LARGEST_LTE)); + confirmInt(3, invokeMatch(new NumberEval(5), ae, MATCH_EXACT)); + + confirmInt(8, invokeMatch(new StringEval("CHARLES"), ae, MATCH_EXACT)); + + confirmInt(4, invokeMatch(new StringEval("Ben"), ae, MATCH_LARGEST_LTE)); + + confirmInt(13, invokeMatch(new StringEval("ED"), ae, MATCH_LARGEST_LTE)); + confirmInt(9, invokeMatch(new StringEval("ED"), ae, MATCH_EXACT)); + + confirmInt(13, invokeMatch(new StringEval("Hugh"), ae, MATCH_LARGEST_LTE)); + assertEquals(ErrorEval.NA, invokeMatch(new StringEval("Hugh"), ae, MATCH_EXACT)); + + confirmInt(11, invokeMatch(new NumberEval(30), ae, MATCH_LARGEST_LTE)); + confirmInt(12, invokeMatch(BoolEval.TRUE, ae, MATCH_LARGEST_LTE)); + } + + + /** + * Ensures that the match_type argument can be an AreaEval.
    + * Bugzilla 44421 + */ + public void testMatchArgTypeArea() { + + ValueEval[] values = { + new NumberEval(4), + new NumberEval(5), + new NumberEval(10), + new NumberEval(10), + new NumberEval(25), + }; + + AreaEval ae = createAreaEval("A1:A5", values); + + AreaEval matchAE = createAreaEval("C1:C1", new ValueEval[] { MATCH_LARGEST_LTE, }); + + try { + confirmInt(4, invokeMatch(new NumberEval(10), ae, matchAE)); + } catch (RuntimeException e) { + if(e.getMessage().startsWith("Unexpected match_type type")) { + // identified bug 44421 + fail(e.getMessage()); + } + // some other error ?? + throw e; + } + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMathX.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMathX.java new file mode 100644 index 0000000000..eb576506a0 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMathX.java @@ -0,0 +1,909 @@ +/* +* 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 23, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class TestMathX extends AbstractNumericTestCase { + + public void testAcosh() { + double d = 0; + + d = MathX.acosh(0); + assertTrue("Acosh 0 is NaN", Double.isNaN(d)); + + d = MathX.acosh(1); + assertEquals("Acosh 1 ", 0, d); + + d = MathX.acosh(-1); + assertTrue("Acosh -1 is NaN", Double.isNaN(d)); + + d = MathX.acosh(100); + assertEquals("Acosh 100 ", 5.298292366d, d); + + d = MathX.acosh(101.001); + assertEquals("Acosh 101.001 ", 5.308253091d, d); + + d = MathX.acosh(200000); + assertEquals("Acosh 200000 ", 12.89921983d, d); + + } + + public void testAsinh() { + double d = 0; + + d = MathX.asinh(0); + assertEquals("asinh 0", d, 0); + + d = MathX.asinh(1); + assertEquals("asinh 1 ", 0.881373587, d); + + d = MathX.asinh(-1); + assertEquals("asinh -1 ", -0.881373587, d); + + d = MathX.asinh(-100); + assertEquals("asinh -100 ", -5.298342366, d); + + d = MathX.asinh(100); + assertEquals("asinh 100 ", 5.298342366, d); + + d = MathX.asinh(200000); + assertEquals("asinh 200000", 12.899219826096400, d); + + d = MathX.asinh(-200000); + assertEquals("asinh -200000 ", -12.899223853137, d); + + } + + public void testAtanh() { + double d = 0; + d = MathX.atanh(0); + assertEquals("atanh 0", d, 0); + + d = MathX.atanh(1); + assertEquals("atanh 1 ", Double.POSITIVE_INFINITY, d); + + d = MathX.atanh(-1); + assertEquals("atanh -1 ", Double.NEGATIVE_INFINITY, d); + + d = MathX.atanh(-100); + assertEquals("atanh -100 ", Double.NaN, d); + + d = MathX.atanh(100); + assertEquals("atanh 100 ", Double.NaN, d); + + d = MathX.atanh(200000); + assertEquals("atanh 200000", Double.NaN, d); + + d = MathX.atanh(-200000); + assertEquals("atanh -200000 ", Double.NaN, d); + + d = MathX.atanh(0.1); + assertEquals("atanh 0.1", 0.100335348, d); + + d = MathX.atanh(-0.1); + assertEquals("atanh -0.1 ", -0.100335348, d); + + } + + public void testCosh() { + double d = 0; + d = MathX.cosh(0); + assertEquals("cosh 0", 1, d); + + d = MathX.cosh(1); + assertEquals("cosh 1 ", 1.543080635, d); + + d = MathX.cosh(-1); + assertEquals("cosh -1 ", 1.543080635, d); + + d = MathX.cosh(-100); + assertEquals("cosh -100 ", 1.344058570908070E+43, d); + + d = MathX.cosh(100); + assertEquals("cosh 100 ", 1.344058570908070E+43, d); + + d = MathX.cosh(15); + assertEquals("cosh 15", 1634508.686, d); + + d = MathX.cosh(-15); + assertEquals("cosh -15 ", 1634508.686, d); + + d = MathX.cosh(0.1); + assertEquals("cosh 0.1", 1.005004168, d); + + d = MathX.cosh(-0.1); + assertEquals("cosh -0.1 ", 1.005004168, d); + + } + + public void testTanh() { + double d = 0; + d = MathX.tanh(0); + assertEquals("tanh 0", 0, d); + + d = MathX.tanh(1); + assertEquals("tanh 1 ", 0.761594156, d); + + d = MathX.tanh(-1); + assertEquals("tanh -1 ", -0.761594156, d); + + d = MathX.tanh(-100); + assertEquals("tanh -100 ", -1, d); + + d = MathX.tanh(100); + assertEquals("tanh 100 ", 1, d); + + d = MathX.tanh(15); + assertEquals("tanh 15", 1, d); + + d = MathX.tanh(-15); + assertEquals("tanh -15 ", -1, d); + + d = MathX.tanh(0.1); + assertEquals("tanh 0.1", 0.099667995, d); + + d = MathX.tanh(-0.1); + assertEquals("tanh -0.1 ", -0.099667995, d); + + } + + public void testMax() { + double[] d = new double[100]; + d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; + d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; + d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; + d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; + d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; + + double m = MathX.max(d); + assertEquals("Max ", 20.1, m); + + d = new double[1000]; + m = MathX.max(d); + assertEquals("Max ", 0, m); + + d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; + d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; + d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; + d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; + d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; + m = MathX.max(d); + assertEquals("Max ", 20.1, m); + + d = new double[20]; + d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; + d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; + d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; + d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; + d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; + m = MathX.max(d); + assertEquals("Max ", -1.1, m); + + } + + public void testMin() { + double[] d = new double[100]; + d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; + d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; + d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; + d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; + d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; + + double m = MathX.min(d); + assertEquals("Min ", 0, m); + + d = new double[20]; + d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; + d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; + d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; + d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; + d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; + + m = MathX.min(d); + assertEquals("Min ", 1.1, m); + + d = new double[1000]; + m = MathX.min(d); + assertEquals("Min ", 0, m); + + d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; + d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; + d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; + d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; + d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; + m = MathX.min(d); + assertEquals("Min ", -19.1, m); + + d = new double[20]; + d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; + d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; + d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; + d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; + d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; + m = MathX.min(d); + assertEquals("Min ", -20.1, m); + } + + public void testProduct() { + double[] d = new double[100]; + d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; + d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; + d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; + d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; + d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; + + double m = MathX.min(d); + assertEquals("Min ", 0, m); + + d = new double[20]; + d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; + d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; + d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; + d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; + d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; + + m = MathX.min(d); + assertEquals("Min ", 1.1, m); + + d = new double[1000]; + m = MathX.min(d); + assertEquals("Min ", 0, m); + + d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; + d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; + d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; + d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; + d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; + m = MathX.min(d); + assertEquals("Min ", -19.1, m); + + d = new double[20]; + d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; + d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; + d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; + d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; + d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; + m = MathX.min(d); + assertEquals("Min ", -20.1, m); + } + + public void testMod() { + } + + public void testNChooseK() { + int n=100; + int k=50; + double d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 1.00891344545564E29, d); + + n = -1; k = 1; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", Double.NaN, d); + + n = 1; k = -1; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", Double.NaN, d); + + n = 0; k = 1; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", Double.NaN, d); + + n = 1; k = 0; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 1, d); + + n = 10; k = 9; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 10, d); + + n = 10; k = 10; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 1, d); + + n = 10; k = 1; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 10, d); + + n = 1000; k = 1; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 1000, d); // awesome ;) + + n = 1000; k = 2; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 499500, d); // awesome ;) + + n = 13; k = 7; + d = MathX.nChooseK(n, k); + assertEquals("NChooseK ", 1716, d); + + } + + public void testSign() { + final short minus = -1; + final short zero = 0; + final short plus = 1; + double d = 0; + + + assertEquals("Sign ", minus, MathX.sign(minus)); + assertEquals("Sign ", plus, MathX.sign(plus)); + assertEquals("Sign ", zero, MathX.sign(zero)); + + d = 0; + assertEquals("Sign ", zero, MathX.sign(d)); + + d = -1.000001; + assertEquals("Sign ", minus, MathX.sign(d)); + + d = -.000001; + assertEquals("Sign ", minus, MathX.sign(d)); + + d = -1E-200; + assertEquals("Sign ", minus, MathX.sign(d)); + + d = Double.NEGATIVE_INFINITY; + assertEquals("Sign ", minus, MathX.sign(d)); + + d = -200.11; + assertEquals("Sign ", minus, MathX.sign(d)); + + d = -2000000000000.11; + assertEquals("Sign ", minus, MathX.sign(d)); + + d = 1.000001; + assertEquals("Sign ", plus, MathX.sign(d)); + + d = .000001; + assertEquals("Sign ", plus, MathX.sign(d)); + + d = 1E-200; + assertEquals("Sign ", plus, MathX.sign(d)); + + d = Double.POSITIVE_INFINITY; + assertEquals("Sign ", plus, MathX.sign(d)); + + d = 200.11; + assertEquals("Sign ", plus, MathX.sign(d)); + + d = 2000000000000.11; + assertEquals("Sign ", plus, MathX.sign(d)); + + } + + public void testSinh() { + double d = 0; + d = MathX.sinh(0); + assertEquals("sinh 0", 0, d); + + d = MathX.sinh(1); + assertEquals("sinh 1 ", 1.175201194, d); + + d = MathX.sinh(-1); + assertEquals("sinh -1 ", -1.175201194, d); + + d = MathX.sinh(-100); + assertEquals("sinh -100 ", -1.344058570908070E+43, d); + + d = MathX.sinh(100); + assertEquals("sinh 100 ", 1.344058570908070E+43, d); + + d = MathX.sinh(15); + assertEquals("sinh 15", 1634508.686, d); + + d = MathX.sinh(-15); + assertEquals("sinh -15 ", -1634508.686, d); + + d = MathX.sinh(0.1); + assertEquals("sinh 0.1", 0.10016675, d); + + d = MathX.sinh(-0.1); + assertEquals("sinh -0.1 ", -0.10016675, d); + + } + + public void testSum() { + double[] d = new double[100]; + d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; + d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; + d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; + d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; + d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; + + double s = MathX.sum(d); + assertEquals("Sum ", 212, s); + + d = new double[1000]; + s = MathX.sum(d); + assertEquals("Sum ", 0, s); + + d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; + d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; + d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; + d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; + d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; + s = MathX.sum(d); + assertEquals("Sum ", 10, s); + + d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; + d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; + d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; + d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; + d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; + s = MathX.sum(d); + assertEquals("Sum ", -212, s); + + } + + public void testSumproduct() { + double d = 0; + double[][] darr = new double[][] + {{0 ,0.11 ,23.23}, + {1 ,0.22 ,46.46}, + {2 ,0.33 ,69.69}, + {3 ,0.44 ,92.92}, + {4 ,0.55 ,116.15}, + {5 ,0.66 ,139.38}, + {6 ,0.77 ,162.61}, + {7 ,0.88 ,185.84}, + {8 ,0.99 ,209.07}, + {9 ,1.1 ,232.3}, + {10 ,1.21 ,255.53}}; + d = MathX.sumproduct(darr); + assertEquals("Sumproduct ", 4.243234425E+22, d); + darr = new double[][] + {{0 ,0.11 ,23.23}, + {0 ,0.22 ,46.46}, + {0 ,0.33 ,69.69}, + {0 ,0.44 ,92.92}, + {0 ,0.55 ,116.15}, + {0 ,0.66 ,139.38}, + {0 ,0.77 ,162.61}, + {0 ,0.88 ,185.84}, + {0 ,0.99 ,209.07}, + {0 ,1.1 ,232.3}, + {0 ,1.21 ,255.53}}; + d = MathX.sumproduct(darr); + assertEquals("Sumproduct ", 4.243234425E+22, d); + + darr = new double[][] + {{0, 0, 0, 0, 0, 0, 0, 0}, + {0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88}, + {23.23, 46.46, 69.69, 92.92, 116.15, 139.38, 162.61, 185.84}}; + d = MathX.sumproduct(darr); + assertEquals("Sumproduct ", 0, d); + + darr = new double[][] + {{0, 1, 2, 3, 4, 5, 6, 7}, + {0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 0.77, 0.88}, + {23.23, 46.46, 69.69, 92.92, 116.15, 139.38, 162.61, 185.84}}; + d = MathX.sumproduct(darr); + assertEquals("Sumproduct ", 2790.3876, d); + + + } + + public void testSumsq() { + double[] d = new double[100]; + d[0] = 1.1; d[1] = 2.1; d[2] = 3.1; d[3] = 4.1; + d[4] = 5.1; d[5] = 6.1; d[6] = 7.1; d[7] = 8.1; + d[8] = 9.1; d[9] = 10.1; d[10] = 11.1; d[11] = 12.1; + d[12] = 13.1; d[13] = 14.1; d[14] = 15.1; d[15] = 16.1; + d[16] = 17.1; d[17] = 18.1; d[18] = 19.1; d[19] = 20.1; + + double s = MathX.sumsq(d); + assertEquals("Sumsq ", 2912.2, s); + + d = new double[1000]; + s = MathX.sumsq(d); + assertEquals("Sumsq ", 0, s); + + d[0] = -1.1; d[1] = 2.1; d[2] = -3.1; d[3] = 4.1; + d[4] = -5.1; d[5] = 6.1; d[6] = -7.1; d[7] = 8.1; + d[8] = -9.1; d[9] = 10.1; d[10] = -11.1; d[11] = 12.1; + d[12] = -13.1; d[13] = 14.1; d[14] = -15.1; d[15] = 16.1; + d[16] = -17.1; d[17] = 18.1; d[18] = -19.1; d[19] = 20.1; + s = MathX.sumsq(d); + assertEquals("Sumsq ", 2912.2, s); + + d[0] = -1.1; d[1] = -2.1; d[2] = -3.1; d[3] = -4.1; + d[4] = -5.1; d[5] = -6.1; d[6] = -7.1; d[7] = -8.1; + d[8] = -9.1; d[9] = -10.1; d[10] = -11.1; d[11] = -12.1; + d[12] = -13.1; d[13] = -14.1; d[14] = -15.1; d[15] = -16.1; + d[16] = -17.1; d[17] = -18.1; d[18] = -19.1; d[19] = -20.1; + s = MathX.sumsq(d); + assertEquals("Sumsq ", 2912.2, s); + } + + public void testFactorial() { + int n = 0; + double s = 0; + + n = 0; + s = MathX.factorial(n); + assertEquals("Factorial ", 1, s); + + n = 1; + s = MathX.factorial(n); + assertEquals("Factorial ", 1, s); + + n = 10; + s = MathX.factorial(n); + assertEquals("Factorial ", 3628800, s); + + n = 99; + s = MathX.factorial(n); + assertEquals("Factorial ", 9.33262154439E+155, s); + + n = -1; + s = MathX.factorial(n); + assertEquals("Factorial ", Double.NaN, s); + + n = Integer.MAX_VALUE; + s = MathX.factorial(n); + assertEquals("Factorial ", Double.POSITIVE_INFINITY, s); + } + + public void testSumx2my2() { + double d = 0; + double[] xarr = null; + double[] yarr = null; + + xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + d = MathX.sumx2my2(xarr, yarr); + assertEquals("sumx2my2 ", 100, d); + + xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}; + yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + d = MathX.sumx2my2(xarr, yarr); + assertEquals("sumx2my2 ", 100, d); + + xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + d = MathX.sumx2my2(xarr, yarr); + assertEquals("sumx2my2 ", -100, d); + + xarr = new double[]{10}; + yarr = new double[]{9}; + d = MathX.sumx2my2(xarr, yarr); + assertEquals("sumx2my2 ", 19, d); + + xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + d = MathX.sumx2my2(xarr, yarr); + assertEquals("sumx2my2 ", 0, d); + + } + + public void testSumx2py2() { + double d = 0; + double[] xarr = null; + double[] yarr = null; + + xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + d = MathX.sumx2py2(xarr, yarr); + assertEquals("sumx2py2 ", 670, d); + + xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}; + yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + d = MathX.sumx2py2(xarr, yarr); + assertEquals("sumx2py2 ", 670, d); + + xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + d = MathX.sumx2py2(xarr, yarr); + assertEquals("sumx2py2 ", 670, d); + + xarr = new double[]{10}; + yarr = new double[]{9}; + d = MathX.sumx2py2(xarr, yarr); + assertEquals("sumx2py2 ", 181, d); + + xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + d = MathX.sumx2py2(xarr, yarr); + assertEquals("sumx2py2 ", 770, d); + } + + public void testSumxmy2() { + double d = 0; + double[] xarr = null; + double[] yarr = null; + + xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + d = MathX.sumxmy2(xarr, yarr); + assertEquals("sumxmy2 ", 10, d); + + xarr = new double[]{-1, -2, -3, -4, -5, -6, -7, -8, -9, -10}; + yarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + d = MathX.sumxmy2(xarr, yarr); + assertEquals("sumxmy2 ", 1330, d); + + xarr = new double[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + d = MathX.sumxmy2(xarr, yarr); + assertEquals("sumxmy2 ", 10, d); + + xarr = new double[]{10}; + yarr = new double[]{9}; + d = MathX.sumxmy2(xarr, yarr); + assertEquals("sumxmy2 ", 1, d); + + xarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + yarr = new double[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + d = MathX.sumxmy2(xarr, yarr); + assertEquals("sumxmy2 ", 0, d); + } + + public void testRound() { + double d = 0; + int p = 0; + + d = 0; p = 0; + assertEquals("round ", 0, MathX.round(d, p)); + + d = 10; p = 0; + assertEquals("round ", 10, MathX.round(d, p)); + + d = 123.23; p = 0; + assertEquals("round ", 123, MathX.round(d, p)); + + d = -123.23; p = 0; + assertEquals("round ", -123, MathX.round(d, p)); + + d = 123.12; p = 2; + assertEquals("round ", 123.12, MathX.round(d, p)); + + d = 88.123459; p = 5; + assertEquals("round ", 88.12346, MathX.round(d, p)); + + d = 0; p = 2; + assertEquals("round ", 0, MathX.round(d, p)); + + d = 0; p = -1; + assertEquals("round ", 0, MathX.round(d, p)); + + d = 0.01; p = -1; + assertEquals("round ", 0, MathX.round(d, p)); + + d = 123.12; p = -2; + assertEquals("round ", 100, MathX.round(d, p)); + + d = 88.123459; p = -3; + assertEquals("round ", 0, MathX.round(d, p)); + + d = 49.00000001; p = -1; + assertEquals("round ", 50, MathX.round(d, p)); + + d = 149.999999; p = -2; + assertEquals("round ", 100, MathX.round(d, p)); + + d = 150.0; p = -2; + assertEquals("round ", 200, MathX.round(d, p)); + } + + public void testRoundDown() { + double d = 0; + int p = 0; + + d = 0; p = 0; + assertEquals("roundDown ", 0, MathX.roundDown(d, p)); + + d = 10; p = 0; + assertEquals("roundDown ", 10, MathX.roundDown(d, p)); + + d = 123.99; p = 0; + assertEquals("roundDown ", 123, MathX.roundDown(d, p)); + + d = -123.99; p = 0; + assertEquals("roundDown ", -123, MathX.roundDown(d, p)); + + d = 123.99; p = 2; + assertEquals("roundDown ", 123.99, MathX.roundDown(d, p)); + + d = 88.123459; p = 5; + assertEquals("roundDown ", 88.12345, MathX.roundDown(d, p)); + + d = 0; p = 2; + assertEquals("roundDown ", 0, MathX.roundDown(d, p)); + + d = 0; p = -1; + assertEquals("roundDown ", 0, MathX.roundDown(d, p)); + + d = 0.01; p = -1; + assertEquals("roundDown ", 0, MathX.roundDown(d, p)); + + d = 199.12; p = -2; + assertEquals("roundDown ", 100, MathX.roundDown(d, p)); + + d = 88.123459; p = -3; + assertEquals("roundDown ", 0, MathX.roundDown(d, p)); + + d = 99.00000001; p = -1; + assertEquals("roundDown ", 90, MathX.roundDown(d, p)); + + d = 100.00001; p = -2; + assertEquals("roundDown ", 100, MathX.roundDown(d, p)); + + d = 150.0; p = -2; + assertEquals("roundDown ", 100, MathX.roundDown(d, p)); + } + + public void testRoundUp() { + double d = 0; + int p = 0; + + d = 0; p = 0; + assertEquals("roundUp ", 0, MathX.roundUp(d, p)); + + d = 10; p = 0; + assertEquals("roundUp ", 10, MathX.roundUp(d, p)); + + d = 123.23; p = 0; + assertEquals("roundUp ", 124, MathX.roundUp(d, p)); + + d = -123.23; p = 0; + assertEquals("roundUp ", -124, MathX.roundUp(d, p)); + + d = 123.12; p = 2; + assertEquals("roundUp ", 123.12, MathX.roundUp(d, p)); + + d = 88.123459; p = 5; + assertEquals("roundUp ", 88.12346, MathX.roundUp(d, p)); + + d = 0; p = 2; + assertEquals("roundUp ", 0, MathX.roundUp(d, p)); + + d = 0; p = -1; + assertEquals("roundUp ", 0, MathX.roundUp(d, p)); + + d = 0.01; p = -1; + assertEquals("roundUp ", 10, MathX.roundUp(d, p)); + + d = 123.12; p = -2; + assertEquals("roundUp ", 200, MathX.roundUp(d, p)); + + d = 88.123459; p = -3; + assertEquals("roundUp ", 1000, MathX.roundUp(d, p)); + + d = 49.00000001; p = -1; + assertEquals("roundUp ", 50, MathX.roundUp(d, p)); + + d = 149.999999; p = -2; + assertEquals("roundUp ", 200, MathX.roundUp(d, p)); + + d = 150.0; p = -2; + assertEquals("roundUp ", 200, MathX.roundUp(d, p)); + } + + public void testCeiling() { + double d = 0; + double s = 0; + + d = 0; s = 0; + assertEquals("ceiling ", 0, MathX.ceiling(d, s)); + + d = 1; s = 0; + assertEquals("ceiling ", 0, MathX.ceiling(d, s)); + + d = 0; s = 1; + assertEquals("ceiling ", 0, MathX.ceiling(d, s)); + + d = -1; s = 0; + assertEquals("ceiling ", 0, MathX.ceiling(d, s)); + + d = 0; s = -1; + assertEquals("ceiling ", 0, MathX.ceiling(d, s)); + + d = 10; s = 1.11; + assertEquals("ceiling ", 11.1, MathX.ceiling(d, s)); + + d = 11.12333; s = 0.03499; + assertEquals("ceiling ", 11.12682, MathX.ceiling(d, s)); + + d = -11.12333; s = 0.03499; + assertEquals("ceiling ", Double.NaN, MathX.ceiling(d, s)); + + d = 11.12333; s = -0.03499; + assertEquals("ceiling ", Double.NaN, MathX.ceiling(d, s)); + + d = -11.12333; s = -0.03499; + assertEquals("ceiling ", -11.12682, MathX.ceiling(d, s)); + + d = 100; s = 0.001; + assertEquals("ceiling ", 100, MathX.ceiling(d, s)); + + d = -0.001; s = -9.99; + assertEquals("ceiling ", -9.99, MathX.ceiling(d, s)); + + d = 4.42; s = 0.05; + assertEquals("ceiling ", 4.45, MathX.ceiling(d, s)); + + d = 0.05; s = 4.42; + assertEquals("ceiling ", 4.42, MathX.ceiling(d, s)); + + d = 0.6666; s = 3.33; + assertEquals("ceiling ", 3.33, MathX.ceiling(d, s)); + + d = 2d/3; s = 3.33; + assertEquals("ceiling ", 3.33, MathX.ceiling(d, s)); + } + + public void testFloor() { + double d = 0; + double s = 0; + + d = 0; s = 0; + assertEquals("floor ", 0, MathX.floor(d, s)); + + d = 1; s = 0; + assertEquals("floor ", Double.NaN, MathX.floor(d, s)); + + d = 0; s = 1; + assertEquals("floor ", 0, MathX.floor(d, s)); + + d = -1; s = 0; + assertEquals("floor ", Double.NaN, MathX.floor(d, s)); + + d = 0; s = -1; + assertEquals("floor ", 0, MathX.floor(d, s)); + + d = 10; s = 1.11; + assertEquals("floor ", 9.99, MathX.floor(d, s)); + + d = 11.12333; s = 0.03499; + assertEquals("floor ", 11.09183, MathX.floor(d, s)); + + d = -11.12333; s = 0.03499; + assertEquals("floor ", Double.NaN, MathX.floor(d, s)); + + d = 11.12333; s = -0.03499; + assertEquals("floor ", Double.NaN, MathX.floor(d, s)); + + d = -11.12333; s = -0.03499; + assertEquals("floor ", -11.09183, MathX.floor(d, s)); + + d = 100; s = 0.001; + assertEquals("floor ", 100, MathX.floor(d, s)); + + d = -0.001; s = -9.99; + assertEquals("floor ", 0, MathX.floor(d, s)); + + d = 4.42; s = 0.05; + assertEquals("floor ", 4.4, MathX.floor(d, s)); + + d = 0.05; s = 4.42; + assertEquals("floor ", 0, MathX.floor(d, s)); + + d = 0.6666; s = 3.33; + assertEquals("floor ", 0, MathX.floor(d, s)); + + d = 2d/3; s = 3.33; + assertEquals("floor ", 0, MathX.floor(d, s)); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java new file mode 100755 index 0000000000..dc3d595aed --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestMid.java @@ -0,0 +1,115 @@ +/* ==================================================================== + 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.AreaPtg; +import org.apache.poi.hssf.record.formula.ReferencePtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.Ref2DEval; +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; + +import junit.framework.TestCase; +/** + * Tests for Excel function MID() + * + * @author Josh Micich + */ +public final class TestMid extends TestCase { + + + private static Eval invokeMid(Eval text, Eval startPos, Eval numChars) { + Eval[] args = new Eval[] { text, startPos, numChars, }; + return new Mid().evaluate(args, -1, (short)-1); + } + + private void confirmMid(Eval text, Eval startPos, Eval numChars, String expected) { + Eval result = invokeMid(text, startPos, numChars); + assertEquals(StringEval.class, result.getClass()); + assertEquals(expected, ((StringEval)result).getStringValue()); + } + + private void confirmMid(Eval text, Eval startPos, Eval numChars, ErrorEval expectedError) { + Eval result = invokeMid(text, startPos, numChars); + assertEquals(ErrorEval.class, result.getClass()); + assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); + } + + public void testBasic() { + + confirmMid(new StringEval("galactic"), new NumberEval(3), new NumberEval(4), "lact"); + } + + /** + * Valid cases where args are not precisely (string, int, int) but can be resolved OK. + */ + public void testUnusualArgs() { + // startPos with fractional digits + confirmMid(new StringEval("galactic"), new NumberEval(3.1), new NumberEval(4), "lact"); + + // string startPos + confirmMid(new StringEval("galactic"), new StringEval("3"), new NumberEval(4), "lact"); + + // text (first) arg type is number, other args are strings with fractional digits + confirmMid(new NumberEval(123456), new StringEval("3.1"), new StringEval("2.9"), "34"); + + // startPos is 1x1 area ref, numChars is cell ref + AreaEval aeStart = new Area2DEval(new AreaPtg("A1:A1"), new ValueEval[] { new NumberEval(2), } ); + RefEval reNumChars = new Ref2DEval(new ReferencePtg("B1"), new NumberEval(3)); + confirmMid(new StringEval("galactic"), aeStart, reNumChars, "ala"); + + confirmMid(new StringEval("galactic"), new NumberEval(3.1), BlankEval.INSTANCE, ""); + + confirmMid(new StringEval("galactic"), new NumberEval(3), BoolEval.FALSE, ""); + confirmMid(new StringEval("galactic"), new NumberEval(3), BoolEval.TRUE, "l"); + confirmMid(BlankEval.INSTANCE, new NumberEval(3), BoolEval.TRUE, ""); + + } + + /** + * Extreme values for startPos and numChars + */ + public void testExtremes() { + confirmMid(new StringEval("galactic"), new NumberEval(4), new NumberEval(400), "actic"); + + confirmMid(new StringEval("galactic"), new NumberEval(30), new NumberEval(4), ""); + confirmMid(new StringEval("galactic"), new NumberEval(3), new NumberEval(0), ""); + } + + /** + * All sorts of ways to make MID return defined errors. + */ + public void testErrors() { + confirmMid(ErrorEval.NAME_INVALID, new NumberEval(3), new NumberEval(4), ErrorEval.NAME_INVALID); + confirmMid(new StringEval("galactic"), ErrorEval.NAME_INVALID, new NumberEval(4), ErrorEval.NAME_INVALID); + confirmMid(new StringEval("galactic"), new NumberEval(3), ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); + confirmMid(new StringEval("galactic"), ErrorEval.DIV_ZERO, ErrorEval.NAME_INVALID, ErrorEval.DIV_ZERO); + + confirmMid(new StringEval("galactic"), BlankEval.INSTANCE, new NumberEval(3.1), ErrorEval.VALUE_INVALID); + + confirmMid(new StringEval("galactic"), new NumberEval(0), new NumberEval(4), ErrorEval.VALUE_INVALID); + confirmMid(new StringEval("galactic"), new NumberEval(1), new NumberEval(-1), ErrorEval.VALUE_INVALID); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java new file mode 100755 index 0000000000..f114662985 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestOffset.java @@ -0,0 +1,92 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula.functions; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.functions.Offset.LinearOffsetRange; + +/** + * Tests for OFFSET function implementation + * + * @author Josh Micich + */ +public final class TestOffset extends TestCase { + + + private static void confirmDoubleConvert(double doubleVal, int expected) { + assertEquals(expected, Offset.convertDoubleToInt(doubleVal)); + } + /** + * Excel's double to int conversion (for function 'OFFSET()') behaves more like Math.floor(). + * Note - negative values are not symmetrical + */ + public void testDoubleConversion() { + + confirmDoubleConvert(100.09, 100); + confirmDoubleConvert(100.01, 100); + confirmDoubleConvert(100.00, 100); + confirmDoubleConvert(99.99, 99); + + confirmDoubleConvert(+2.01, +2); + confirmDoubleConvert(+2.00, +2); + confirmDoubleConvert(+1.99, +1); + confirmDoubleConvert(+1.01, +1); + confirmDoubleConvert(+1.00, +1); + confirmDoubleConvert(+0.99, 0); + confirmDoubleConvert(+0.01, 0); + confirmDoubleConvert( 0.00, 0); + confirmDoubleConvert(-0.01, -1); + confirmDoubleConvert(-0.99, -1); + confirmDoubleConvert(-1.00, -1); + confirmDoubleConvert(-1.01, -2); + confirmDoubleConvert(-1.99, -2); + confirmDoubleConvert(-2.00, -2); + confirmDoubleConvert(-2.01, -3); + } + + public void testLinearOffsetRange() { + LinearOffsetRange lor; + + lor = new LinearOffsetRange(3, 2); + assertEquals(3, lor.getFirstIndex()); + assertEquals(4, lor.getLastIndex()); + lor = lor.normaliseAndTranslate(0); // expected no change + assertEquals(3, lor.getFirstIndex()); + assertEquals(4, lor.getLastIndex()); + + lor = lor.normaliseAndTranslate(5); + assertEquals(8, lor.getFirstIndex()); + assertEquals(9, lor.getLastIndex()); + + // negative length + + lor = new LinearOffsetRange(6, -4).normaliseAndTranslate(0); + assertEquals(3, lor.getFirstIndex()); + assertEquals(6, lor.getLastIndex()); + + + // bounds checking + lor = new LinearOffsetRange(0, 100); + assertFalse(lor.isOutOfBounds(0, 16383)); + lor = lor.normaliseAndTranslate(16300); + assertTrue(lor.isOutOfBounds(0, 16383)); + assertFalse(lor.isOutOfBounds(0, 65535)); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestPmt.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestPmt.java new file mode 100644 index 0000000000..935615acae --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestPmt.java @@ -0,0 +1,87 @@ +/* ==================================================================== + 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 junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.usermodel.HSSFErrorConstants; + +/** + * + * @author Josh Micich + */ +public final class TestPmt extends TestCase { + + private static void confirm(double expected, NumberEval ne) { + // only asserting accuracy to 4 fractional digits + assertEquals(expected, ne.getNumberValue(), 0.00005); + } + private static Eval invoke(Eval[] args) { + return new Pmt().evaluate(args, -1, (short)-1); + } + /** + * Invocation when not expecting an error result + */ + private static NumberEval invokeNormal(Eval[] args) { + Eval ev = invoke(args); + if(ev instanceof ErrorEval) { + throw new AssertionFailedError("Normal evaluation failed with error code: " + + ev.toString()); + } + return (NumberEval) ev; + } + + private static void confirm(double expected, double rate, double nper, double pv, double fv, boolean isBeginning) { + Eval[] args = { + new NumberEval(rate), + new NumberEval(nper), + new NumberEval(pv), + new NumberEval(fv), + new NumberEval(isBeginning ? 1 : 0), + }; + confirm(expected, invokeNormal(args)); + } + + + public void testBasic() { + confirm(-1037.0321, (0.08/12), 10, 10000, 0, false); + confirm(-1030.1643, (0.08/12), 10, 10000, 0, true); + } + + public void test3args() { + + Eval[] args = { + new NumberEval(0.005), + new NumberEval(24), + new NumberEval(1000), + }; + Eval ev = invoke(args); + if(ev instanceof ErrorEval) { + ErrorEval err = (ErrorEval) ev; + if(err.getErrorCode() == HSSFErrorConstants.ERROR_VALUE) { + throw new AssertionFailedError("Identified bug 44691"); + } + } + + confirm(-44.3206, invokeNormal(args)); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestRoundFuncs.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestRoundFuncs.java new file mode 100755 index 0000000000..a6ce345aeb --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestRoundFuncs.java @@ -0,0 +1,49 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.formula.functions; + +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; + +import junit.framework.TestCase; + +/** + * Test cases for ROUND(), ROUNDUP(), ROUNDDOWN() + * + * @author Josh Micich + */ +public final class TestRoundFuncs extends TestCase { + public void testRounddownWithStringArg() { + + Eval strArg = new StringEval("abc"); + Eval[] args = { strArg, new NumberEval(2), }; + Eval result = new Rounddown().evaluate(args, -1, (short)-1); + assertEquals(ErrorEval.VALUE_INVALID, result); + } + + public void testRoundupWithStringArg() { + + Eval strArg = new StringEval("abc"); + Eval[] args = { strArg, new NumberEval(2), }; + Eval result = new Roundup().evaluate(args, -1, (short)-1); + assertEquals(ErrorEval.VALUE_INVALID, result); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestRowCol.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestRowCol.java new file mode 100755 index 0000000000..4002c30d0f --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestRowCol.java @@ -0,0 +1,102 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.eval.Eval; + +/** + * Tests for ROW(), ROWS(), COLUMN(), COLUMNS() + * + * @author Josh Micich + */ +public final class TestRowCol extends TestCase { + + public TestRowCol(String testName) { + super(testName); + } + + public void testCol() { + Function target = new Column(); + { + Eval[] args = { EvalFactory.createRefEval("C5"), }; + double actual = NumericFunctionInvoker.invoke(target, args); + assertEquals(3, actual, 0D); + } + { + Eval[] args = { EvalFactory.createAreaEval("E2:H12", 4, 11), }; + double actual = NumericFunctionInvoker.invoke(target, args); + assertEquals(5, actual, 0D); + } + } + + public void testRow() { + Function target = new Row(); + { + Eval[] args = { EvalFactory.createRefEval("C5"), }; + double actual = NumericFunctionInvoker.invoke(target, args); + assertEquals(5, actual, 0D); + } + { + Eval[] args = { EvalFactory.createAreaEval("E2:H12", 4, 11), }; + double actual = NumericFunctionInvoker.invoke(target, args); + assertEquals(2, actual, 0D); + } + } + + public void testColumns() { + + confirmColumnsFunc("A1:F1", 6, 1); + confirmColumnsFunc("A1:C2", 3, 2); + confirmColumnsFunc("A1:B3", 2, 3); + confirmColumnsFunc("A1:A6", 1, 6); + + Eval[] args = { EvalFactory.createRefEval("C5"), }; + double actual = NumericFunctionInvoker.invoke(new Columns(), args); + assertEquals(1, actual, 0D); + } + + public void testRows() { + + confirmRowsFunc("A1:F1", 6, 1); + confirmRowsFunc("A1:C2", 3, 2); + confirmRowsFunc("A1:B3", 2, 3); + confirmRowsFunc("A1:A6", 1, 6); + + Eval[] args = { EvalFactory.createRefEval("C5"), }; + double actual = NumericFunctionInvoker.invoke(new Rows(), args); + assertEquals(1, actual, 0D); + } + + private static void confirmRowsFunc(String areaRefStr, int nCols, int nRows) { + Eval[] args = { EvalFactory.createAreaEval(areaRefStr, nCols, nRows), }; + + double actual = NumericFunctionInvoker.invoke(new Rows(), args); + assertEquals(nRows, actual, 0D); + } + + + private static void confirmColumnsFunc(String areaRefStr, int nCols, int nRows) { + Eval[] args = { EvalFactory.createAreaEval(areaRefStr, nCols, nRows), }; + + double actual = NumericFunctionInvoker.invoke(new Columns(), args); + assertEquals(nCols, actual, 0D); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestStatsLib.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestStatsLib.java new file mode 100644 index 0000000000..237366baf0 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestStatsLib.java @@ -0,0 +1,262 @@ +/* +* 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 30, 2005 + * + */ +package org.apache.poi.hssf.record.formula.functions; + + +/** + * @author Amol S. Deshmukh < amolweb at ya hoo dot com > + * + */ +public class TestStatsLib extends AbstractNumericTestCase { + + public void testDevsq() { + double[] v = null; + double d, x = 0; + + v = new double[] {1,2,3,4,5,6,7,8,9,10}; + d = StatsLib.devsq(v); + x = 82.5; + assertEquals("devsq ", x, d); + + v = new double[] {1,1,1,1,1,1,1,1,1,1}; + d = StatsLib.devsq(v); + x = 0; + assertEquals("devsq ", x, d); + + v = new double[] {0,0,0,0,0,0,0,0,0,0}; + d = StatsLib.devsq(v); + x = 0; + assertEquals("devsq ", x, d); + + v = new double[] {1,2,1,2,1,2,1,2,1,2}; + d = StatsLib.devsq(v); + x = 2.5; + assertEquals("devsq ", x, d); + + v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; + d = StatsLib.devsq(v); + x = 10953.7416965767; + assertEquals("devsq ", x, d); + + v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; + d = StatsLib.devsq(v); + x = 82.5; + assertEquals("devsq ", x, d); + } + + public void testKthLargest() { + double[] v = null; + double d, x = 0; + + v = new double[] {1,2,3,4,5,6,7,8,9,10}; + d = StatsLib.kthLargest(v, 3); + x = 8; + assertEquals("kthLargest ", x, d); + + v = new double[] {1,1,1,1,1,1,1,1,1,1}; + d = StatsLib.kthLargest(v, 3); + x = 1; + assertEquals("kthLargest ", x, d); + + v = new double[] {0,0,0,0,0,0,0,0,0,0}; + d = StatsLib.kthLargest(v, 3); + x = 0; + assertEquals("kthLargest ", x, d); + + v = new double[] {1,2,1,2,1,2,1,2,1,2}; + d = StatsLib.kthLargest(v, 3); + x = 2; + assertEquals("kthLargest ", x, d); + + v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; + d = StatsLib.kthLargest(v, 3); + x = 5.37828; + assertEquals("kthLargest ", x, d); + + v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; + d = StatsLib.kthLargest(v, 3); + x = -3; + assertEquals("kthLargest ", x, d); + } + + public void testKthSmallest() { + } + + public void testAvedev() { + double[] v = null; + double d, x = 0; + + v = new double[] {1,2,3,4,5,6,7,8,9,10}; + d = StatsLib.avedev(v); + x = 2.5; + assertEquals("avedev ", x, d); + + v = new double[] {1,1,1,1,1,1,1,1,1,1}; + d = StatsLib.avedev(v); + x = 0; + assertEquals("avedev ", x, d); + + v = new double[] {0,0,0,0,0,0,0,0,0,0}; + d = StatsLib.avedev(v); + x = 0; + assertEquals("avedev ", x, d); + + v = new double[] {1,2,1,2,1,2,1,2,1,2}; + d = StatsLib.avedev(v); + x = 0.5; + assertEquals("avedev ", x, d); + + v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; + d = StatsLib.avedev(v); + x = 36.42176053333; + assertEquals("avedev ", x, d); + + v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; + d = StatsLib.avedev(v); + x = 2.5; + assertEquals("avedev ", x, d); + } + + public void testMedian() { + double[] v = null; + double d, x = 0; + + v = new double[] {1,2,3,4,5,6,7,8,9,10}; + d = StatsLib.median(v); + x = 5.5; + assertEquals("median ", x, d); + + v = new double[] {1,1,1,1,1,1,1,1,1,1}; + d = StatsLib.median(v); + x = 1; + assertEquals("median ", x, d); + + v = new double[] {0,0,0,0,0,0,0,0,0,0}; + d = StatsLib.median(v); + x = 0; + assertEquals("median ", x, d); + + v = new double[] {1,2,1,2,1,2,1,2,1,2}; + d = StatsLib.median(v); + x = 1.5; + assertEquals("median ", x, d); + + v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; + d = StatsLib.median(v); + x = 5.37828; + assertEquals("median ", x, d); + + v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; + d = StatsLib.median(v); + x = -5.5; + assertEquals("median ", x, d); + + v = new double[] {-2,-3,-4,-5,-6,-7,-8,-9,-10}; + d = StatsLib.median(v); + x = -6; + assertEquals("median ", x, d); + + v = new double[] {1,2,3,4,5,6,7,8,9}; + d = StatsLib.median(v); + x = 5; + assertEquals("median ", x, d); + } + + public void testMode() { + double[] v = null; + double d, x = 0; + + v = new double[] {1,2,3,4,5,6,7,8,9,10}; + d = StatsLib.mode(v); + x = Double.NaN; + assertEquals("mode ", x, d); + + v = new double[] {1,1,1,1,1,1,1,1,1,1}; + d = StatsLib.mode(v); + x = 1; + assertEquals("mode ", x, d); + + v = new double[] {0,0,0,0,0,0,0,0,0,0}; + d = StatsLib.mode(v); + x = 0; + assertEquals("mode ", x, d); + + v = new double[] {1,2,1,2,1,2,1,2,1,2}; + d = StatsLib.mode(v); + x = 1; + assertEquals("mode ", x, d); + + v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; + d = StatsLib.mode(v); + x = Double.NaN; + assertEquals("mode ", x, d); + + v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; + d = StatsLib.mode(v); + x = Double.NaN; + assertEquals("mode ", x, d); + + v = new double[] {1,2,3,4,1,1,1,1,0,0,0,0,0}; + d = StatsLib.mode(v); + x = 1; + assertEquals("mode ", x, d); + + v = new double[] {0,1,2,3,4,1,1,1,0,0,0,0,1}; + d = StatsLib.mode(v); + x = 0; + assertEquals("mode ", x, d); + } + + public void testStddev() { + double[] v = null; + double d, x = 0; + + v = new double[] {1,2,3,4,5,6,7,8,9,10}; + d = StatsLib.stdev(v); + x = 3.02765035410; + assertEquals("stdev ", x, d); + + v = new double[] {1,1,1,1,1,1,1,1,1,1}; + d = StatsLib.stdev(v); + x = 0; + assertEquals("stdev ", x, d); + + v = new double[] {0,0,0,0,0,0,0,0,0,0}; + d = StatsLib.stdev(v); + x = 0; + assertEquals("stdev ", x, d); + + v = new double[] {1,2,1,2,1,2,1,2,1,2}; + d = StatsLib.stdev(v); + x = 0.52704627669; + assertEquals("stdev ", x, d); + + v = new double[] {123.12,33.3333,2d/3d,5.37828,0.999}; + d = StatsLib.stdev(v); + x = 52.33006233652; + assertEquals("stdev ", x, d); + + v = new double[] {-1,-2,-3,-4,-5,-6,-7,-8,-9,-10}; + d = StatsLib.stdev(v); + x = 3.02765035410; + assertEquals("stdev ", x, d); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java new file mode 100755 index 0000000000..73043911f4 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestSumproduct.java @@ -0,0 +1,120 @@ +/* ==================================================================== + 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.ReferencePtg; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.NumericValueEval; +import org.apache.poi.hssf.record.formula.eval.Ref2DEval; +import org.apache.poi.hssf.record.formula.eval.RefEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +import junit.framework.TestCase; + +/** + * Test cases for SUMPRODUCT() + * + * @author Josh Micich + */ +public final class TestSumproduct extends TestCase { + + private static Eval invokeSumproduct(Eval[] args) { + // srcCellRow and srcCellColumn are ignored by SUMPRODUCT + return new Sumproduct().evaluate(args, -1, (short)-1); + } + private static void confirmDouble(double expected, Eval actualEval) { + if(!(actualEval instanceof NumericValueEval)) { + fail("Expected numeric result"); + } + NumericValueEval nve = (NumericValueEval)actualEval; + assertEquals(expected, nve.getNumberValue(), 0); + } + + public void testScalarSimple() { + + RefEval refEval = new Ref2DEval(new ReferencePtg("A1"), new NumberEval(3)); + Eval[] args = { + refEval, + new NumberEval(2), + }; + Eval result = invokeSumproduct(args); + confirmDouble(6D, result); + } + + + public void testAreaSimple() { + + AreaEval aeA = EvalFactory.createAreaEval("A1:A3", 1, 3); + AreaEval aeB = EvalFactory.createAreaEval("B1:B3", 1, 3); + ValueEval[] aValues = aeA.getValues(); + ValueEval[] bValues = aeB.getValues(); + aValues[0] = new NumberEval(2); + aValues[1] = new NumberEval(4); + aValues[2] = new NumberEval(5); + bValues[0] = new NumberEval(3); + bValues[1] = new NumberEval(6); + bValues[2] = new NumberEval(7); + + Eval[] args = { aeA, aeB, }; + Eval result = invokeSumproduct(args); + confirmDouble(65D, result); + } + + /** + * For scalar products, the terms may be 1x1 area refs + */ + public void testOneByOneArea() { + + AreaEval ae = EvalFactory.createAreaEval("A1:A1", 1, 1); + ae.getValues()[0] = new NumberEval(7); + + Eval[] args = { + ae, + new NumberEval(2), + }; + Eval result = invokeSumproduct(args); + confirmDouble(14D, result); + } + + + public void testMismatchAreaDimensions() { + + AreaEval aeA = EvalFactory.createAreaEval("A1:A3", 1, 3); + AreaEval aeB = EvalFactory.createAreaEval("B1:D1", 3, 1); + + Eval[] args; + args = new Eval[] { aeA, aeB, }; + assertEquals(ErrorEval.VALUE_INVALID, invokeSumproduct(args)); + + args = new Eval[] { aeA, new NumberEval(5), }; + assertEquals(ErrorEval.VALUE_INVALID, invokeSumproduct(args)); + } + + public void testAreaWithErrorCell() { + AreaEval aeA = EvalFactory.createAreaEval("A1:A2", 1, 2); + AreaEval aeB = EvalFactory.createAreaEval("B1:B2", 1, 2); + aeB.getValues()[1] = ErrorEval.REF_INVALID; + + Eval[] args = { aeA, aeB, }; + assertEquals(ErrorEval.REF_INVALID, invokeSumproduct(args)); + } + +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java new file mode 100755 index 0000000000..4d63cad1c5 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTFunc.java @@ -0,0 +1,118 @@ +/* ==================================================================== + 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.ReferencePtg; +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.Ref2DEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; + +import junit.framework.TestCase; + +/** + * Test cases for Excel function T() + * + * @author Josh Micich + */ +public final class TestTFunc extends TestCase { + + /** + * @return the result of calling function T() with the specified argument + */ + private static Eval invokeT(Eval arg) { + Eval[] args = { arg, }; + Eval result = new T().evaluate(args, -1, (short)-1); + assertNotNull("result may never be null", result); + return result; + } + /** + * Simulates call: T(A1) + * where cell A1 has the specified innerValue + */ + private Eval invokeTWithReference(ValueEval innerValue) { + Eval arg = new Ref2DEval(new ReferencePtg((short)1, (short)1, false, false), innerValue); + return invokeT(arg); + } + + private static void confirmText(String text) { + Eval arg = new StringEval(text); + Eval eval = invokeT(arg); + StringEval se = (StringEval) eval; + assertEquals(text, se.getStringValue()); + } + + public void testTextValues() { + + confirmText("abc"); + confirmText(""); + confirmText(" "); + confirmText("~"); + confirmText("123"); + confirmText("TRUE"); + } + + private static void confirmError(Eval arg) { + Eval eval = invokeT(arg); + assertTrue(arg == eval); + } + + public void testErrorValues() { + + confirmError(ErrorEval.VALUE_INVALID); + confirmError(ErrorEval.NA); + confirmError(ErrorEval.REF_INVALID); + } + + private static void confirmString(Eval eval, String expected) { + assertTrue(eval instanceof StringEval); + assertEquals(expected, ((StringEval)eval).getStringValue()); + } + + private static void confirmOther(Eval arg) { + Eval eval = invokeT(arg); + confirmString(eval, ""); + } + + public void testOtherValues() { + confirmOther(new NumberEval(2)); + confirmOther(BoolEval.FALSE); + confirmOther(BlankEval.INSTANCE); // can this particular case be verified? + } + + public void testRefValues() { + Eval eval; + + eval = invokeTWithReference(new StringEval("def")); + confirmString(eval, "def"); + eval = invokeTWithReference(new StringEval(" ")); + confirmString(eval, " "); + + eval = invokeTWithReference(new NumberEval(2)); + confirmString(eval, ""); + eval = invokeTWithReference(BoolEval.TRUE); + confirmString(eval, ""); + + eval = invokeTWithReference(ErrorEval.NAME_INVALID); + assertTrue(eval == ErrorEval.NAME_INVALID); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTrim.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTrim.java new file mode 100755 index 0000000000..076ac1fc7e --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestTrim.java @@ -0,0 +1,78 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +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.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.StringEval; +/** + * Tests for Excel function TRIM() + * + * @author Josh Micich + */ +public final class TestTrim extends TestCase { + + + private static Eval invokeTrim(Eval text) { + Eval[] args = new Eval[] { text, }; + return new Trim().evaluate(args, -1, (short)-1); + } + + private void confirmTrim(Eval text, String expected) { + Eval result = invokeTrim(text); + assertEquals(StringEval.class, result.getClass()); + assertEquals(expected, ((StringEval)result).getStringValue()); + } + + private void confirmTrim(Eval text, ErrorEval expectedError) { + Eval result = invokeTrim(text); + assertEquals(ErrorEval.class, result.getClass()); + assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); + } + + public void testBasic() { + + confirmTrim(new StringEval(" hi "), "hi"); + confirmTrim(new StringEval("hi "), "hi"); + confirmTrim(new StringEval(" hi"), "hi"); + confirmTrim(new StringEval(" hi there "), "hi there"); + confirmTrim(new StringEval(""), ""); + confirmTrim(new StringEval(" "), ""); + } + + /** + * Valid cases where text arg is not exactly a string + */ + public void testUnusualArgs() { + + // text (first) arg type is number, other args are strings with fractional digits + confirmTrim(new NumberEval(123456), "123456"); + confirmTrim(BoolEval.FALSE, "FALSE"); + confirmTrim(BoolEval.TRUE, "TRUE"); + confirmTrim(BlankEval.INSTANCE, ""); + } + + public void testErrors() { + confirmTrim(ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); + } +} diff --git a/src/testcases/org/apache/poi/hssf/record/formula/functions/TestXYNumericFunction.java b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestXYNumericFunction.java new file mode 100755 index 0000000000..c9f043bd3b --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/formula/functions/TestXYNumericFunction.java @@ -0,0 +1,139 @@ +/* ==================================================================== + 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 junit.framework.TestCase; + +import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.hssf.record.formula.eval.Area2DEval; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.record.formula.eval.ValueEval; +/** + * Tests for Excel functions SUMX2MY2(), SUMX2PY2(), SUMXMY2() + * + * @author Josh Micich + */ +public final class TestXYNumericFunction extends TestCase { + private static final Function SUM_SQUARES = new Sumx2py2(); + private static final Function DIFF_SQUARES = new Sumx2my2(); + private static final Function SUM_SQUARES_OF_DIFFS = new Sumxmy2(); + + private static Eval invoke(Function function, Eval xArray, Eval yArray) { + Eval[] args = new Eval[] { xArray, yArray, }; + return function.evaluate(args, -1, (short)-1); + } + + private void confirm(Function function, Eval xArray, Eval yArray, double expected) { + Eval result = invoke(function, xArray, yArray); + assertEquals(NumberEval.class, result.getClass()); + assertEquals(expected, ((NumberEval)result).getNumberValue(), 0); + } + private void confirmError(Function function, Eval xArray, Eval yArray, ErrorEval expectedError) { + Eval result = invoke(function, xArray, yArray); + assertEquals(ErrorEval.class, result.getClass()); + assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); + } + + private void confirmError(Eval xArray, Eval yArray, ErrorEval expectedError) { + confirmError(SUM_SQUARES, xArray, yArray, expectedError); + confirmError(DIFF_SQUARES, xArray, yArray, expectedError); + confirmError(SUM_SQUARES_OF_DIFFS, xArray, yArray, expectedError); + } + + public void testBasic() { + ValueEval[] xValues = { + new NumberEval(1), + new NumberEval(2), + }; + ValueEval areaEvalX = createAreaEval(xValues); + confirm(SUM_SQUARES, areaEvalX, areaEvalX, 10.0); + confirm(DIFF_SQUARES, areaEvalX, areaEvalX, 0.0); + confirm(SUM_SQUARES_OF_DIFFS, areaEvalX, areaEvalX, 0.0); + + ValueEval[] yValues = { + new NumberEval(3), + new NumberEval(4), + }; + ValueEval areaEvalY = createAreaEval(yValues); + confirm(SUM_SQUARES, areaEvalX, areaEvalY, 30.0); + confirm(DIFF_SQUARES, areaEvalX, areaEvalY, -20.0); + confirm(SUM_SQUARES_OF_DIFFS, areaEvalX, areaEvalY, 8.0); + } + + /** + * number of items in array is not limited to 30 + */ + public void testLargeArrays() { + ValueEval[] xValues = createMockNumberArray(100, 3); + ValueEval[] yValues = createMockNumberArray(100, 2); + + confirm(SUM_SQUARES, createAreaEval(xValues), createAreaEval(yValues), 1300.0); + confirm(DIFF_SQUARES, createAreaEval(xValues), createAreaEval(yValues), 500.0); + confirm(SUM_SQUARES_OF_DIFFS, createAreaEval(xValues), createAreaEval(yValues), 100.0); + } + + + private ValueEval[] createMockNumberArray(int size, double value) { + ValueEval[] result = new ValueEval[size]; + for (int i = 0; i < result.length; i++) { + result[i] = new NumberEval(value); + } + return result; + } + + private static ValueEval createAreaEval(ValueEval[] values) { + String refStr = "A1:A" + values.length; + return new Area2DEval(new AreaPtg(refStr), values); + } + + public void testErrors() { + ValueEval[] xValues = { + ErrorEval.REF_INVALID, + new NumberEval(2), + }; + ValueEval areaEvalX = createAreaEval(xValues); + ValueEval[] yValues = { + new NumberEval(2), + ErrorEval.NULL_INTERSECTION, + }; + ValueEval areaEvalY = createAreaEval(yValues); + ValueEval[] zValues = { // wrong size + new NumberEval(2), + }; + ValueEval areaEvalZ = createAreaEval(zValues); + + // if either arg is an error, that error propagates + confirmError(ErrorEval.REF_INVALID, ErrorEval.NAME_INVALID, ErrorEval.REF_INVALID); + confirmError(areaEvalX, ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); + confirmError(ErrorEval.NAME_INVALID, areaEvalX, ErrorEval.NAME_INVALID); + + // array sizes must match + confirmError(areaEvalX, areaEvalZ, ErrorEval.NA); + confirmError(areaEvalZ, areaEvalY, ErrorEval.NA); + + // any error in an array item propagates up + confirmError(areaEvalX, areaEvalX, ErrorEval.REF_INVALID); + + // search for errors array by array, not pair by pair + confirmError(areaEvalX, areaEvalY, ErrorEval.REF_INVALID); + confirmError(areaEvalY, areaEvalX, ErrorEval.NULL_INTERSECTION); + + } +} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java new file mode 100644 index 0000000000..c849fd4369 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBug42464.java @@ -0,0 +1,94 @@ +/* ==================================================================== + 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.usermodel; + +import java.io.File; +import java.io.FileInputStream; +import java.util.Iterator; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.poi.hssf.record.FormulaRecord; +import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; +import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue; +import org.apache.poi.hssf.util.CellReference; + +public final class TestBug42464 extends TestCase { + String dirname; + + protected void setUp() throws Exception { + super.setUp(); + dirname = System.getProperty("HSSF.testdata.path"); + } + + public void testOKFile() throws Exception { + HSSFWorkbook wb = new HSSFWorkbook( + new FileInputStream(new File(dirname,"42464-ExpPtg-ok.xls")) + ); + process(wb); + } + public void testExpSharedBadFile() throws Exception { + HSSFWorkbook wb = new HSSFWorkbook( + new FileInputStream(new File(dirname,"42464-ExpPtg-bad.xls")) + ); + process(wb); + } + + protected void process(HSSFWorkbook wb) { + for(int i=0; i " + cell.getCellFormula()); + } + + CellValue evalResult = eval.evaluate(cell); + assertNotNull(evalResult); + } + } +} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBug43093.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBug43093.java new file mode 100644 index 0000000000..ce072e9e01 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBug43093.java @@ -0,0 +1,59 @@ +/* ==================================================================== + 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.usermodel; + +import junit.framework.TestCase; + +public class TestBug43093 extends TestCase { + + private static void addNewSheetWithCellsA1toD4(HSSFWorkbook book, int sheet) { + + HSSFSheet sht = book .createSheet("s" + sheet); + for (short r=0; r < 4; r++) { + + HSSFRow row = sht.createRow (r); + for (short c=0; c < 4; c++) { + + HSSFCell cel = row.createCell(c); + /**/ cel.setCellValue(sheet*100 + r*10 + c); + } + } + } + + public void testBug43093() throws Exception { + HSSFWorkbook xlw = new HSSFWorkbook(); + + addNewSheetWithCellsA1toD4(xlw, 1); + addNewSheetWithCellsA1toD4(xlw, 2); + addNewSheetWithCellsA1toD4(xlw, 3); + addNewSheetWithCellsA1toD4(xlw, 4); + + HSSFSheet s2 = xlw.getSheet("s2"); + HSSFRow s2r3 = s2.getRow(3); + HSSFCell s2E4 = s2r3.createCell((short)4); + /**/ s2E4.setCellFormula("SUM(s3!B2:C3)"); + + HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(s2, xlw); + eva.setCurrentRow(s2r3); + double d = eva.evaluate(s2E4).getNumberValue(); + + // internalEvaluate(...) Area3DEval.: 311+312+321+322 expected + assertEquals(d, (double)(311+312+321+322), 0.0000001); + // System.out.println("Area3DEval ok.: 311+312+321+322=" + d); + } +} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java new file mode 100644 index 0000000000..87a760f714 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorBugs.java @@ -0,0 +1,257 @@ +/* ==================================================================== + 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.usermodel; + +import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; +import org.apache.poi.hssf.record.formula.AreaPtg; +import org.apache.poi.hssf.record.formula.FuncVarPtg; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import junit.framework.TestCase; + +public final class TestFormulaEvaluatorBugs extends TestCase { + private String dirName; + private String tmpDirName; + + protected void setUp() throws Exception { + super.setUp(); + dirName = System.getProperty("HSSF.testdata.path"); + tmpDirName = System.getProperty("java.io.tmpdir"); + } + + /** + * An odd problem with evaluateFormulaCell giving the + * right values when file is opened, but changes + * to the source data in some versions of excel + * doesn't cause them to be updated. However, other + * versions of excel, and gnumeric, work just fine + * WARNING - tedious bug where you actually have to + * open up excel + */ + public void test44636() throws Exception { + // Open the existing file, tweak one value and + // re-calculate + FileInputStream in = new FileInputStream(new File(dirName,"44636.xls")); + HSSFWorkbook wb = new HSSFWorkbook(in); + HSSFSheet sheet = wb.getSheetAt (0); + HSSFRow row = sheet.getRow (0); + + row.getCell((short)0).setCellValue(4.2); + row.getCell((short)2).setCellValue(25); + + HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); + assertEquals(4.2*25, row.getCell((short)3).getNumericCellValue(), 0.0001); + + // Save + File existing = new File(tmpDirName,"44636-existing.xls"); + FileOutputStream out = new FileOutputStream(existing); + wb.write(out); + out.close(); + System.err.println("Existing file for bug #44636 written to " + existing.toString()); + + + // Now, do a new file from scratch + wb = new HSSFWorkbook(); + sheet = wb.createSheet(); + + row = sheet.createRow(0); + row.createCell((short)0).setCellValue(1.2); + row.createCell((short)1).setCellValue(4.2); + + row = sheet.createRow(1); + row.createCell((short)0).setCellFormula("SUM(A1:B1)"); + + HSSFFormulaEvaluator.evaluateAllFormulaCells(wb); + assertEquals(5.4, row.getCell((short)0).getNumericCellValue(), 0.0001); + + // Save + File scratch = new File(tmpDirName,"44636-scratch.xls"); + out = new FileOutputStream(scratch); + wb.write(out); + out.close(); + System.err.println("New file for bug #44636 written to " + scratch.toString()); + } + + /** + * Bug 44297: 32767+32768 is evaluated to -1 + * Fix: IntPtg must operate with unsigned short. Reading signed short results in incorrect formula calculation + * if a formula has values in the interval [Short.MAX_VALUE, (Short.MAX_VALUE+1)*2] + * + * @author Yegor Kozlov + */ + public void test44297() throws IOException { + FileInputStream in = new FileInputStream(new File(dirName, "44297.xls")); + HSSFWorkbook wb = new HSSFWorkbook(in); + in.close(); + + HSSFRow row; + HSSFCell cell; + + HSSFSheet sheet = wb.getSheetAt(0); + + HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); + + row = (HSSFRow)sheet.getRow(0); + cell = row.getCell((short)0); + assertEquals("31+46", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(77, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(1); + cell = row.getCell((short)0); + assertEquals("30+53", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(83, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(2); + cell = row.getCell((short)0); + assertEquals("SUM(A1:A2)", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(160, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(4); + cell = row.getCell((short)0); + assertEquals("32767+32768", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(7); + cell = row.getCell((short)0); + assertEquals("32744+42333", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(8); + cell = row.getCell((short)0); + assertEquals("327680.0/32768", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(10, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(9); + cell = row.getCell((short)0); + assertEquals("32767+32769", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(10); + cell = row.getCell((short)0); + assertEquals("35000+36000", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0); + + row = (HSSFRow)sheet.getRow(11); + cell = row.getCell((short)0); + assertEquals("-1000000.0-3000000.0", cell.getCellFormula()); + eva.setCurrentRow(row); + assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0); + } + + /** + * Bug 44410: SUM(C:C) is valid in excel, and means a sum + * of all the rows in Column C + * + * @author Nick Burch + */ + public void test44410() throws IOException { + FileInputStream in = new FileInputStream(new File(dirName, "SingleLetterRanges.xls")); + HSSFWorkbook wb = new HSSFWorkbook(in); + in.close(); + + HSSFSheet sheet = wb.getSheetAt(0); + + HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb); + + // =index(C:C,2,1) -> 2 + HSSFRow rowIDX = (HSSFRow)sheet.getRow(3); + // =sum(C:C) -> 6 + HSSFRow rowSUM = (HSSFRow)sheet.getRow(4); + // =sum(C:D) -> 66 + HSSFRow rowSUM2D = (HSSFRow)sheet.getRow(5); + + // Test the sum + HSSFCell cellSUM = rowSUM.getCell((short)0); + + FormulaRecordAggregate frec = + (FormulaRecordAggregate)cellSUM.getCellValueRecord(); + List ops = frec.getFormulaRecord().getParsedExpression(); + assertEquals(2, ops.size()); + assertEquals(AreaPtg.class, ops.get(0).getClass()); + assertEquals(FuncVarPtg.class, ops.get(1).getClass()); + + // Actually stored as C1 to C65536 + // (last row is -1 === 65535) + AreaPtg ptg = (AreaPtg)ops.get(0); + assertEquals(2, ptg.getFirstColumn()); + assertEquals(2, ptg.getLastColumn()); + assertEquals(0, ptg.getFirstRow()); + assertEquals(65535, ptg.getLastRow()); + assertEquals("C:C", ptg.toFormulaString(wb.getWorkbook())); + + // Will show as C:C, but won't know how many + // rows it covers as we don't have the sheet + // to hand when turning the Ptgs into a string + assertEquals("SUM(C:C)", cellSUM.getCellFormula()); + eva.setCurrentRow(rowSUM); + + // But the evaluator knows the sheet, so it + // can do it properly + assertEquals(6, eva.evaluate(cellSUM).getNumberValue(), 0); + + + // Test the index + // Again, the formula string will be right but + // lacking row count, evaluated will be right + HSSFCell cellIDX = rowIDX.getCell((short)0); + assertEquals("INDEX(C:C,2,1)", cellIDX.getCellFormula()); + eva.setCurrentRow(rowIDX); + assertEquals(2, eva.evaluate(cellIDX).getNumberValue(), 0); + + // Across two colums + HSSFCell cellSUM2D = rowSUM2D.getCell((short)0); + assertEquals("SUM(C:D)", cellSUM2D.getCellFormula()); + eva.setCurrentRow(rowSUM2D); + assertEquals(66, eva.evaluate(cellSUM2D).getNumberValue(), 0); + } + + /** + * Tests that we can evaluate boolean cells properly + */ + public void testEvaluateBooleanInCell_bug44508() { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet sheet = wb.createSheet(); + wb.setSheetName(0, "Sheet1"); + HSSFRow row = sheet.createRow(0); + HSSFCell cell = row.createCell((short)0); + + cell.setCellFormula("1=1"); + + HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb); + fe.setCurrentRow(row); + try { + fe.evaluateInCell(cell); + } catch (NumberFormatException e) { + fail("Identified bug 44508"); + } + assertEquals(true, cell.getBooleanCellValue()); + } +} diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java new file mode 100644 index 0000000000..6c2e3b6412 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java @@ -0,0 +1,117 @@ +package org.apache.poi.hssf.usermodel; + +import java.util.Iterator; + +import junit.framework.TestCase; + +/** + * Tests to show that our documentation at + * http://poi.apache.org/hssf/eval.html + * all actually works as we'd expect them to + */ +public class TestFormulaEvaluatorDocs extends TestCase { + protected void setUp() throws Exception { + super.setUp(); + } + + /** + * http://poi.apache.org/hssf/eval.html#EvaluateAll + */ + public void testEvaluateAll() throws Exception { + HSSFWorkbook wb = new HSSFWorkbook(); + HSSFSheet s1 = wb.createSheet(); + HSSFSheet s2 = wb.createSheet(); + wb.setSheetName(0, "S1"); + wb.setSheetName(1, "S2"); + + HSSFRow s1r1 = s1.createRow(0); + HSSFRow s1r2 = s1.createRow(1); + HSSFRow s2r1 = s2.createRow(0); + + HSSFCell s1r1c1 = s1r1.createCell((short)0); + HSSFCell s1r1c2 = s1r1.createCell((short)1); + HSSFCell s1r1c3 = s1r1.createCell((short)2); + s1r1c1.setCellValue(22.3); + s1r1c2.setCellValue(33.4); + s1r1c3.setCellFormula("SUM(A1:B1)"); + + HSSFCell s1r2c1 = s1r2.createCell((short)0); + HSSFCell s1r2c2 = s1r2.createCell((short)1); + HSSFCell s1r2c3 = s1r2.createCell((short)2); + s1r2c1.setCellValue(-1.2); + s1r2c2.setCellValue(-3.4); + s1r2c3.setCellFormula("SUM(A2:B2)"); + + HSSFCell s2r1c1 = s2r1.createCell((short)0); + s2r1c1.setCellFormula("S1!A1"); + + // Not evaluated yet + assertEquals(0.0, s1r1c3.getNumericCellValue(), 0); + assertEquals(0.0, s1r2c3.getNumericCellValue(), 0); + assertEquals(0.0, s2r1c1.getNumericCellValue(), 0); + + // Do a full evaluate, as per our docs + // uses evaluateFormulaCell() + for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) { + HSSFSheet sheet = wb.getSheetAt(sheetNum); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + + for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { + HSSFRow r = (HSSFRow)rit.next(); + evaluator.setCurrentRow(r); + + for(Iterator cit = r.cellIterator(); cit.hasNext();) { + HSSFCell c = (HSSFCell)cit.next(); + if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) { + evaluator.evaluateFormulaCell(c); + + // For testing - all should be numeric + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, evaluator.evaluateFormulaCell(c)); + } + } + } + } + + // Check now as expected + assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0); + assertEquals("SUM(A1:B1)", wb.getSheetAt(0).getRow(0).getCell((short)2).getCellFormula()); + assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType()); + + assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0); + assertEquals("SUM(A2:B2)", wb.getSheetAt(0).getRow(1).getCell((short)2).getCellFormula()); + assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType()); + + assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0); + assertEquals("'S1'!A1", wb.getSheetAt(1).getRow(0).getCell((short)0).getCellFormula()); + assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType()); + + + // Now do the alternate call, which zaps the formulas + // uses evaluateInCell() + for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) { + HSSFSheet sheet = wb.getSheetAt(sheetNum); + HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb); + + for(Iterator rit = sheet.rowIterator(); rit.hasNext();) { + HSSFRow r = (HSSFRow)rit.next(); + evaluator.setCurrentRow(r); + + for(Iterator cit = r.cellIterator(); cit.hasNext();) { + HSSFCell c = (HSSFCell)cit.next(); + if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) { + evaluator.evaluateInCell(c); + } + } + } + } + + assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0); + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType()); + + assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0); + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType()); + + assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0); + assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType()); + } +}