</path>
- <path id="examples.classpath">
- <path refid="main.classpath"/>
- <pathelement location="${main.output.dir}"/>
- </path>
+ <path id="examples.classpath">
+ <path refid="main.classpath"/>
+ <pathelement location="${main.output.dir}"/>
+ </path>
fork="yes" srcdir="${main.src.test}">
<classpath>
<path refid="main.classpath"/>
- <pathelement location="${main.output.dir}"/>
+ <pathelement path="${main.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
fork="yes" srcdir="${scratchpad.src.test}">
<classpath>
<path refid="scratchpad.classpath"/>
- <pathelement location="${scratchpad.output.dir}"/>
+ <pathelement path="${scratchpad.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
fork="yes" srcdir="${contrib.src.test}">
<classpath>
<path refid="contrib.classpath"/>
- <pathelement location="${contrib.output.dir}"/>
+ <pathelement path="${contrib.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
</target>
- <target name="compile-examples" depends="init">
+ <target name="compile-examples" depends="init,compile-ooxml">
<javac target="${jdk.version.class}" source="${jdk.version.source}"
- destdir="${examples.output.dir}" debug="on" srcdir="${examples.src}">
+ failonerror="true" destdir="${examples.output.dir}" debug="on" fork="yes"
+ srcdir="${examples.src}">
<classpath>
<path refid="examples.classpath"/>
<path refid="ooxml.classpath"/>
- <pathelement location="${ooxml.output.dir}"/>
+ <pathelement path="${ooxml.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
fork="yes" srcdir="${ooxml.src.test}">
<classpath>
<path refid="ooxml.classpath"/>
- <pathelement location="${ooxml.output.dir}"/>
+ <pathelement path="${ooxml.output.dir}"/>
<pathelement location="${junit.jar1.dir}"/>
</classpath>
</javac>
</devs>
<!-- Don't forget to update status.xml too! -->
- <release version="3.1-beta1" date="2008-??-??">
+ <release version="3.0.3-beta1" date="2008-04-??">
+ <action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action>
+ <action dev="POI-DEVELOPERS" type="add">Move the missing record aware eventusermodel code out of scratchpad</action>
<action dev="POI-DEVELOPERS" type="add">44652 / 44603 - Improved handling of Pictures in Word Documents</action>
<action dev="POI-DEVELOPERS" type="fix">44636 - Fix formula parsing of RefVPtg, which was causing #VALUE to be shown on subsequent edits</action>
<action dev="POI-DEVELOPERS" type="fix">44627 - Improve the thread safety of POILogFactory</action>
<!-- Don't forget to update changes.xml too! -->
<changes>
- <release version="3.1-beta1" date="2008-??-??">
+ <release version="3.0.3-beta1" date="2008-04-??">
+ <action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action>
+ <action dev="POI-DEVELOPERS" type="add">Move the missing record aware eventusermodel code out of scratchpad</action>
<action dev="POI-DEVELOPERS" type="add">44652 / 44603 - Improved handling of Pictures in Word Documents</action>
<action dev="POI-DEVELOPERS" type="fix">44636 - Fix formula parsing of RefVPtg, which was causing #VALUE to be shown on subsequent edits</action>
<action dev="POI-DEVELOPERS" type="fix">44627 - Improve the thread safety of POILogFactory</action>
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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;
+
+/**
+ * <p>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.</p>
+ * <p>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<rowrec.getRowNumber(); i++) {
+ MissingRowDummyRecord dr = new MissingRowDummyRecord(i);
+ childListener.processRecord(dr);
+ }
+ }
+
+ // Record this as the last row we saw
+ lastSeenRow = rowrec.getRowNumber();
+ break;
+
+
+ // These are all the "cell" records
+
+ case BlankRecord.sid:
+ BlankRecord brec = (BlankRecord) record;
+ thisRow = brec.getRow();
+ thisColumn = brec.getColumn();
+ break;
+ case BoolErrRecord.sid:
+ BoolErrRecord berec = (BoolErrRecord) record;
+ thisRow = berec.getRow();
+ thisColumn = berec.getColumn();
+ break;
+ case FormulaRecord.sid:
+ FormulaRecord frec = (FormulaRecord) record;
+ thisRow = frec.getRow();
+ thisColumn = frec.getColumn();
+ break;
+ case LabelRecord.sid:
+ LabelRecord lrec = (LabelRecord) record;
+ thisRow = lrec.getRow();
+ thisColumn = lrec.getColumn();
+ //System.out.println("Cell found containing String "
+ // + " at row " + lrec.getRow() + " and column " + lrec.getColumn());
+ break;
+ case LabelSSTRecord.sid:
+ LabelSSTRecord lsrec = (LabelSSTRecord) record;
+ thisRow = lsrec.getRow();
+ thisColumn = lsrec.getColumn();
+ //System.out.println("Cell found containing String "
+ // + " at row " + lsrec.getRow() + " and column " + lsrec.getColumn());
+ break;
+ case NoteRecord.sid:
+ NoteRecord nrec = (NoteRecord) record;
+ thisRow = nrec.getRow();
+ thisColumn = nrec.getColumn();
+ break;
+ case NumberRecord.sid:
+ NumberRecord numrec = (NumberRecord) record;
+ thisRow = numrec.getRow();
+ thisColumn = numrec.getColumn();
+ //System.out.println("Cell found with value " + numrec.getValue()
+ // + " at row " + numrec.getRow() + " and column " + numrec.getColumn());
+ break;
+ case RKRecord.sid:
+ RKRecord rkrec = (RKRecord) record;
+ thisRow = rkrec.getRow();
+ thisColumn = rkrec.getColumn();
+ break;
+ default:
+ //System.out.println(record.getClass());
+ break;
+ }
+
+ // Do we need to fire dummy end-of-row records?
+ if(thisRow != lastSeenRow) {
+ for(int i=lastSeenRow; i<thisRow; i++) {
+ int cols = -1;
+ if(i == lastSeenRow) {
+ cols = lastSeenColumn;
+ }
+ LastCellOfRowDummyRecord r = new LastCellOfRowDummyRecord(i, cols);
+ childListener.processRecord(r);
+ }
+ }
+ // If we've finished with the columns, then fire the final
+ // dummy end-of-row record
+ if(lastSeenRow != -1 && lastSeenColumn != -1 && thisRow == -1) {
+ LastCellOfRowDummyRecord r = new LastCellOfRowDummyRecord(lastSeenRow, lastSeenColumn);
+ childListener.processRecord(r);
+
+ lastSeenRow = -1;
+ lastSeenColumn = -1;
+ }
+
+ // If we've moved onto a new row, the ensure we re-set
+ // the column counter
+ if(thisRow != lastSeenRow) {
+ lastSeenColumn = -1;
+ }
+
+ // Do we need to fire dummy cell records?
+ if(lastSeenColumn != (thisColumn-1)) {
+ for(int i=lastSeenColumn+1; i<thisColumn; i++) {
+ MissingCellDummyRecord r = new MissingCellDummyRecord(thisRow, i);
+ childListener.processRecord(r);
+ }
+ }
+
+ // Update cell and row counts if doing cells
+ if(thisColumn != -1) {
+ lastSeenRow = thisRow;
+ lastSeenColumn = thisColumn;
+ }
+
+ childListener.processRecord(record);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.dummyrecord;
+
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * A dummy record to indicate that we've now had the last
+ * cell record for this row.
+ */
+public class LastCellOfRowDummyRecord extends Record {
+ private int row;
+ private int lastColumnNumber;
+
+ public LastCellOfRowDummyRecord(int row, int lastColumnNumber) {
+ this.row = row;
+ this.lastColumnNumber = lastColumnNumber;
+ }
+
+ /**
+ * Returns the (0 based) number of the row we are
+ * currently working on.
+ */
+ public int getRow() { return row; }
+ /**
+ * Returns the (0 based) number of the last column
+ * seen for this row. You should have already been
+ * called with that record.
+ * This is -1 in the case of there being no columns
+ * for the row.
+ */
+ public int getLastColumnNumber() { return lastColumnNumber; }
+
+ protected void fillFields(RecordInputStream in) {
+ }
+ public short getSid() {
+ return -1;
+ }
+ public int serialize(int offset, byte[] data) {
+ return -1;
+ }
+ protected void validateSid(short id) {
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.dummyrecord;
+
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * A dummy record for when we're missing a cell in a row,
+ * but still want to trigger something
+ */
+public class MissingCellDummyRecord extends Record {
+ private int row;
+ private int column;
+
+ public MissingCellDummyRecord(int row, int column) {
+ this.row = row;
+ this.column = column;
+ }
+
+ protected void fillFields(RecordInputStream in) {
+ }
+ public short getSid() {
+ return -1;
+ }
+ public int serialize(int offset, byte[] data) {
+ return -1;
+ }
+ protected void validateSid(short id) {
+ }
+
+ public int getRow() { return row; }
+ public int getColumn() { return column; }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.dummyrecord;
+
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordInputStream;
+
+/**
+ * A dummy record for when we're missing a row, but still
+ * want to trigger something
+ */
+public class MissingRowDummyRecord extends Record {
+ private int rowNumber;
+
+ public MissingRowDummyRecord(int rowNumber) {
+ this.rowNumber = rowNumber;
+ }
+
+ protected void fillFields(RecordInputStream in) {
+ }
+ public short getSid() {
+ return -1;
+ }
+ public int serialize(int offset, byte[] data) {
+ return -1;
+ }
+ protected void validateSid(short id) {
+ }
+
+ public int getRowNumber() {
+ return rowNumber;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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.AddPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * This is a documentation of the observed behaviour of
+ * the '+' operator in Excel:
+ * <ol>
+ * <li> 1+TRUE = 2
+ * <li> 1+FALSE = 1
+ * <li> 1+"true" = #VALUE!
+ * <li> 1+"1" = 2
+ * <li> 1+A1 = #VALUE if A1 contains "1"
+ * <li> 1+A1 = 2 if A1 contains ="1"
+ * <li> 1+A1 = 2 if A1 contains TRUE or =TRUE
+ * <li> 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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);
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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() {
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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:<br/>
+ * <code>(b ? BoolEval.TRUE : BoolEval.FALSE)</code>
+ * @return a <tt>BoolEval</tt> instance representing <tt>b</tt>.
+ */
+ 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+
+ /** <b>#NULL!</b> - Intersection of two cell ranges is empty */
+ public static final ErrorEval NULL_INTERSECTION = new ErrorEval(EC.ERROR_NULL);
+ /** <b>#DIV/0!</b> - Division by zero */
+ public static final ErrorEval DIV_ZERO = new ErrorEval(EC.ERROR_DIV_0);
+ /** <b>#VALUE!</b> - Wrong type of operand */
+ public static final ErrorEval VALUE_INVALID = new ErrorEval(EC.ERROR_VALUE);
+ /** <b>#REF!</b> - Illegal or deleted cell reference */
+ public static final ErrorEval REF_INVALID = new ErrorEval(EC.ERROR_REF);
+ /** <b>#NAME?</b> - Wrong function or range name */
+ public static final ErrorEval NAME_INVALID = new ErrorEval(EC.ERROR_NAME);
+ /** <b>#NUM!</b> - Value range overflow */
+ public static final ErrorEval NUM_ERROR = new ErrorEval(EC.ERROR_NUM);
+ /** <b>#N/A</b> - 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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 {
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <i>within</i> operator and function
+ * implementations. Note - <tt>OperationEval.evaluate()</tt> and <tt>Function.evaluate()</tt>
+ * method signatures do not throw this exception so it cannot propagate outside.<p/>
+ *
+ * Here is an example coded without <tt>EvaluationException</tt>, to show how it can help:
+ * <pre>
+ * 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();
+ * }
+ * // ...
+ * }
+ * </pre>
+ * 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.<br/>
+ * Using <tt>EvaluationException</tt> allows the error returning code to be consolidated to one
+ * place.<p/>
+ * <pre>
+ * 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;
+ *}
+ * </pre>
+ * It is not mandatory to use EvaluationException, doing so might give the following advantages:<br/>
+ * - Methods can more easily be extracted, allowing for re-use.<br/>
+ * - Type management (typecasting etc) is simpler because error conditions have been separated from
+ * intermediate calculation values.<br/>
+ * - Fewer local variables are required. Local variables can have stronger types.<br/>
+ * - 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.<p/>
+ *
+ * <b>Note</b> - Only standard evaluation errors are represented by <tt>EvaluationException</tt> (
+ * 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
+
+ /** <b>#VALUE!</b> - Wrong type of operand */
+ public static EvaluationException invalidValue() {
+ return new EvaluationException(ErrorEval.VALUE_INVALID);
+ }
+ /** <b>#REF!</b> - Illegal or deleted cell reference */
+ public static EvaluationException invalidRef() {
+ return new EvaluationException(ErrorEval.REF_INVALID);
+ }
+ /** <b>#NUM!</b> - Value range overflow */
+ public static EvaluationException numberError() {
+ return new EvaluationException(ErrorEval.NUM_ERROR);
+ }
+
+ public ErrorEval getErrorEval() {
+ return _errorEval;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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
+ * <tt>AbstractFunctionPtg.field_2_fnc_index</tt> == 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);
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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);
+ }
+ }
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt> or <tt>BlankEval</tt>.
+ * Never <code>null</code> or <tt>ErrorEval</tt>.
+ * @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.
+ *
+ * <table border="1" cellpadding="1" cellspacing="1" summary="sample spreadsheet">
+ * <tr><th> </th><th> A </th><th> B </th><th> C </th><th> D </th></tr>
+ * <tr><th>1</th><td>15</td><td>20</td><td>25</td><td> </td></tr>
+ * <tr><th>2</th><td> </td><td> </td><td> </td><td>200</td></tr>
+ * <tr><th>3</th><td> </td><td> </td><td> </td><td>300</td></tr>
+ * <tr><th>3</th><td> </td><td> </td><td> </td><td>400</td></tr>
+ * </table>
+ *
+ * If the formula "=1000+A1:B1+D2:D3" is put into the 9 cells from A2 to C4, the spreadsheet
+ * will look like this:
+ *
+ * <table border="1" cellpadding="1" cellspacing="1" summary="sample spreadsheet">
+ * <tr><th> </th><th> A </th><th> B </th><th> C </th><th> D </th></tr>
+ * <tr><th>1</th><td>15</td><td>20</td><td>25</td><td> </td></tr>
+ * <tr><th>2</th><td>1215</td><td>1220</td><td>#VALUE!</td><td>200</td></tr>
+ * <tr><th>3</th><td>1315</td><td>1320</td><td>#VALUE!</td><td>300</td></tr>
+ * <tr><th>4</th><td>#VALUE!</td><td>#VALUE!</td><td>#VALUE!</td><td>400</td></tr>
+ * </table>
+ *
+ * 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.<p/>
+ *
+ * The same concept is extended to references across sheets, such that even multi-row,
+ * multi-column areas can be useful.<p/>
+ *
+ * Of course with carefully (or carelessly) chosen parameters, cyclic references can occur and
+ * hence this method <b>can</b> throw a 'circular reference' EvaluationException. Note that
+ * this method does not attempt to detect cycles. Every cell in the specified Area <tt>ae</tt>
+ * has already been evaluated prior to this method call. Any cell (or cell<b>s</b>) part of
+ * <tt>ae</tt> that would incur a cyclic reference error if selected by this method, will
+ * already have the value <t>ErrorEval.CIRCULAR_REF_ERROR</tt> 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 <code>null</code>. Never
+ * <tt>ErrorEval</tt>.
+ * @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 <tt>ErrorEval</tt>, and <code>null</code>
+ */
+ 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.<br/>
+ * Value is first coerced to a <tt>double</tt> ( See <tt>coerceValueToDouble()</tt> ).<p/>
+ *
+ * Excel typically converts doubles to integers by truncating toward negative infinity.<br/>
+ * The equivalent java code is:<br/>
+ * <code>return (int)Math.floor(d);</code><br/>
+ * <b>not</b>:<br/>
+ * <code>return (int)d; // wrong - rounds toward zero</code>
+ *
+ */
+ 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 - <tt>BlankEval</tt> is not supported and must be handled by the caller.
+ * @param ev must be a <tt>NumberEval</tt>, <tt>StringEval</tt> or <tt>BoolEval</tt>
+ * @return actual, parsed or interpreted double value (respectively).
+ * @throws EvaluationException(#VALUE!) only if a StringEval is supplied and cannot be parsed
+ * as a double (See <tt>parseDouble()</tt> for allowable formats).
+ * @throws RuntimeException if the supplied parameter is not <tt>NumberEval</tt>,
+ * <tt>StringEval</tt> or <tt>BoolEval</tt>
+ */
+ 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.<br/>
+ * Tolerates currency prefixes, commas, leading and trailing spaces.<p/>
+ *
+ * Some examples:<br/>
+ * " 123 " -> 123.0<br/>
+ * ".123" -> 0.123<br/>
+ * These not supported yet:<br/>
+ * " $ 1,000.00 " -> 1000.0<br/>
+ * "$1.25E4" -> 12500.0<br/>
+ * "5**2" -> 500<br/>
+ * "250%" -> 2.5<br/>
+ *
+ * @param text
+ * @return <code>null</code> 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 <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>, or <tt>BlankEval</tt>
+ * @return the converted string value. never <code>null</code>
+ */
+ 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() + ")");
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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();
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 '%'. <p/>
+ * @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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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 <code>null</code>, possibly empty string.
+ */
+ String getStringValue();
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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<iSize; i++) {
+ if (operands[i] instanceof AreaEval) {
+ AreaEval ae = (AreaEval) operands[i];
+ ValueEval[] values = ae.getValues();
+ for (int j=0, jSize=values.length; j<jSize; j++) {
+ ValueEval tempVe = singleOperandEvaluate(values[j], srcRow, srcCol, true);
+ if (tempVe instanceof BoolEval) {
+ b = b && ((BoolEval) tempVe).getBooleanValue();
+ atleastOneNonBlank = true;
+ }
+ else if (tempVe instanceof ErrorEval) {
+ retval = tempVe;
+ break outer;
+ }
+ }
+ }
+ else {
+ ValueEval tempVe = singleOperandEvaluate(operands[i], srcRow, srcCol, false);
+ if (tempVe instanceof BoolEval) {
+ b = b && ((BoolEval) tempVe).getBooleanValue();
+ atleastOneNonBlank = true;
+ }
+ else if (tempVe instanceof StringEval) {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+ else if (tempVe instanceof ErrorEval) {
+ retval = tempVe;
+ break outer;
+ }
+ }
+ }
+
+ if (!atleastOneNonBlank) {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+
+ if (retval == null) { // if no error
+ retval = b ? BoolEval.TRUE : BoolEval.FALSE;
+ }
+
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Areas extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Argument extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Asc extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class Asin extends NumericFunction {
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ d = Math.asin(d);
+ retval = (Double.isNaN(d))
+ ? (ValueEval) ErrorEval.NUM_ERROR
+ : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * Support for hyperbolic trig functions was added as a part of
+ * Java distribution only in JDK1.5. This class uses custom
+ * naive implementation based on formulas at:
+ * http://www.math2.org/math/trig/hyperbolics.htm
+ * These formulas seem to agree with excel's implementation.
+ *
+ */
+public class Asinh extends NumericFunction {
+
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ d = MathX.asinh(d);
+ retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class Atan extends NumericFunction {
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ d = Math.atan(d);
+ retval = (Double.isNaN(d))
+ ? (ValueEval) ErrorEval.NUM_ERROR
+ : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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 Atan2 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 = (d0 == d1 && d1 == 0)
+ ? Double.NaN
+ : Math.atan2(d1, d0);
+ retval = (Double.isNaN(d) || Double.isInfinite(d))
+ ? (ValueEval) ErrorEval.NUM_ERROR
+ : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * Support for hyperbolic trig functions was added as a part of
+ * Java distribution only in JDK1.5. This class uses custom
+ * naive implementation based on formulas at:
+ * http://www.math2.org/math/trig/hyperbolics.htm
+ * These formulas seem to agree with excel's implementation.
+ *
+ */
+public class Atanh extends NumericFunction {
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ d = MathX.atanh(d);
+ retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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 Avedev 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.avedev(values);
+ retval = (Double.isNaN(d) || Double.isInfinite(d))
+ ? (ValueEval) ErrorEval.NUM_ERROR
+ : new NumberEval(d);
+ }
+
+ return retval;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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 Average 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 = MathX.average(values);
+ retval = (Double.isNaN(d) || Double.isInfinite(d))
+ ? (ValueEval) ErrorEval.NUM_ERROR
+ : new NumberEval(d);
+ }
+
+ return retval;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class Averagea extends NotImplementedFunction {
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Betadist extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Betainv extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Binomdist extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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.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;
+
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ * Here are the general rules concerning Boolean functions:
+ * <ol>
+ * <li> Blanks are not either true or false
+ * <li> Strings are not either true or false (even strings "true"
+ * or "TRUE" or "0" etc.)
+ * <li> Numbers: 0 is false. Any other number is TRUE.
+ * <li> References are evaluated and above rules apply.
+ * <li> Areas: Individual cells in area are evaluated and checked to
+ * see if they are blanks, strings etc.
+ * </ol>
+ */
+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;
+
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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<iSize; i++) {
+ ValueEval ve = singleOperandEvaluate(operands[i], srcCellRow, srcCellCol);
+ if (ve instanceof StringValueEval) {
+ StringValueEval sve = (StringValueEval) ve;
+ sb.append(sve.getStringValue());
+ }
+ else if (ve instanceof BlankEval) {}
+ else {
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ }
+ }
+
+ if (retval == null) {
+ retval = new StringEval(sb.toString());
+ }
+
+ return retval;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Confidence extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Correl extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class Cos extends NumericFunction {
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ d = Math.cos(d);
+ retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 6, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ErrorEval;
+import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.NumberEval;
+import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
+ *
+ */
+public class Cosh extends NumericFunction {
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ double d = 0;
+ ValueEval retval = null;
+
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 1:
+ ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval ne = (NumericValueEval) ve;
+ d = ne.getNumberValue();
+ }
+ else if (ve instanceof BlankEval) {
+ // do nothing
+ }
+ else {
+ retval = ErrorEval.NUM_ERROR;
+ }
+ }
+
+ if (retval == null) {
+ d = MathX.cosh(d);
+ retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Count extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.RefEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+/**
+ * Counts the number of cells that contain data within the list of arguments.
+ *
+ * Excel Syntax
+ * COUNTA(value1,value2,...)
+ * Value1, value2, ... are 1 to 30 arguments representing the values or ranges to be counted.
+ *
+ * @author Josh Micich
+ */
+public final class Counta implements Function {
+
+ public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+ int nArgs = args.length;
+ if (nArgs < 1) {
+ // too few arguments
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ if (nArgs > 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<nArgs; i++) {
+ temp += countArg(args[i]);
+
+ }
+ return new NumberEval(temp);
+ }
+
+ private static int countArg(Eval eval) {
+ if (eval instanceof AreaEval) {
+ AreaEval ae = (AreaEval) eval;
+ return countAreaEval(ae);
+ }
+ if (eval instanceof RefEval) {
+ RefEval refEval = (RefEval)eval;
+ return countValue(refEval.getInnerValueEval());
+ }
+ if (eval instanceof NumberEval) {
+ return 1;
+ }
+ if (eval instanceof StringEval) {
+ return 1;
+ }
+
+
+ throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")");
+ }
+
+ private static int countAreaEval(AreaEval ae) {
+
+ int temp = 0;
+ ValueEval[] values = ae.getValues();
+ for (int i = 0; i < values.length; i++) {
+ ValueEval val = values[i];
+ if(val == null) {
+ // seems to occur. Really we would have expected BlankEval
+ continue;
+ }
+ temp += countValue(val);
+
+ }
+ return temp;
+ }
+
+ private static int countValue(ValueEval valueEval) {
+
+ if(valueEval == BlankEval.INSTANCE) {
+ return 0;
+ }
+
+ if(valueEval instanceof BlankEval) {
+ // wouldn't need this if BlankEval was final
+ return 0;
+ }
+
+ if(valueEval instanceof ErrorEval) {
+ // note - error values are counted
+ return 1;
+ }
+ // also empty strings and zeros are counted too
+
+ return 1;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Countblank extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.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;
+
+/**
+ * Implementation for the function COUNTIF<p/>
+ *
+ * Syntax: COUNTIF ( range, criteria )
+ * <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions">
+ * <tr><th>range </th><td>is the range of cells to be counted based on the criteria</td></tr>
+ * <tr><th>criteria</th><td>is used to determine which cells to count</td></tr>
+ * </table>
+ * <p/>
+ *
+ * @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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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.
+ * <b>Glossary of terms/abbreviations:</b>
+ * <br/>
+ * <ul>
+ * <li><em>FV:</em> Future Value</li>
+ * <li><em>PV:</em> Present Value</li>
+ * <li><em>NPV:</em> Net Present Value</li>
+ * <li><em>PMT:</em> (Periodic) Payment</li>
+ *
+ * </ul>
+ * For more info on the terms/abbreviations please use the references below
+ * (hyperlinks are subject to change):
+ * </br>Online References:
+ * <ol>
+ * <li>GNU Emacs Calc 2.02 Manual: http://theory.uwinnipeg.ca/gnu/calc/calc_203.html</li>
+ * <li>Yahoo Financial Glossary: http://biz.yahoo.com/f/g/nn.html#y</li>
+ * <li>MS Excel function reference: http://office.microsoft.com/en-us/assistance/CH062528251033.aspx</li>
+ * </ol>
+ * <h3>Implementation Notes:</h3>
+ * Symbols used in the formulae that follow:<br/>
+ * <ul>
+ * <li>p: present value</li>
+ * <li>f: future value</li>
+ * <li>n: number of periods</li>
+ * <li>y: payment (in each period)</li>
+ * <li>r: rate</li>
+ * <li>^: the power operator (NOT the java bitwise XOR operator!)</li>
+ * </ul>
+ * [From MS Excel function reference] Following are some of the key formulas
+ * that are used in this implementation:
+ * <pre>
+ * p(1+r)^n + y(1+rt)((1+r)^n-1)/r + f=0 ...{when r!=0}
+ * ny + p + f=0 ...{when r=0}
+ * </pre>
+ */
+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<iSize; i++) {
+ npv += cfs[i] / trate;
+ trate *= r1;
+ }
+ return npv;
+ }
+
+ /**
+ *
+ * @param r
+ * @param n
+ * @param p
+ * @param f
+ * @param t
+ */
+ public static double pmt(double r, double n, double p, double f, boolean t) {
+ double retval = 0;
+ if (r == 0) {
+ retval = -1*(f+p)/n;
+ }
+ else {
+ double r1 = r + 1;
+ retval = ( f + p * Math.pow(r1, n) ) * r
+ /
+ ((t ? r1 : 1) * (1 - Math.pow(r1, n)));
+ }
+ return retval;
+ }
+
+ /**
+ *
+ * @param r
+ * @param y
+ * @param p
+ * @param f
+ * @param t
+ */
+ public static double nper(double r, double y, double p, double f, boolean t) {
+ double retval = 0;
+ if (r == 0) {
+ retval = -1 * (f + p) / y;
+ } else {
+ double r1 = r + 1;
+ double ryr = (t ? r1 : 1) * y / r;
+ double a1 = ((ryr - f) < 0)
+ ? Math.log(f - ryr)
+ : Math.log(ryr - f);
+ double a2 = ((ryr - f) < 0)
+ ? Math.log(-p - ryr)
+ : Math.log(p + ryr);
+ double a3 = Math.log(r1);
+ retval = (a1 - a2) / a3;
+ }
+ return retval;
+ }
+
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Find extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Findb extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Finv extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Fisher extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Fisherinv extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Fixed extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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 Floor 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.floor(d0, d1);
+ retval = (Double.isNaN(d) || Double.isInfinite(d))
+ ? (ValueEval) ErrorEval.NUM_ERROR
+ : new NumberEval(d);
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Forecast extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Formulaconvert extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Fpos extends NotImplementedFunction {
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.Eval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+
+
+/**
+ * For most Excel functions, involving references ((cell, area), (2d, 3d)), the references are
+ * passed in as arguments, and the exact location remains fixed. However, a select few Excel
+ * functions have the ability to access cells that were not part of any reference passed as an
+ * argument.<br/>
+ * Two important functions with this feature are <b>INDIRECT</b> and <b>OFFSET</b><p/>
+ *
+ * In POI, the <tt>HSSFFormulaEvaluator</tt> 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 <tt>evaluate()</tt> method on the common
+ * interface <tt>Function</tt> does not take a workbook parameter.<p>
+ *
+ * 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 <code>null</code>,
+ * 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 <code>null</code>. Possibly an instance of <tt>ErrorEval</tt> 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);
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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);
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.<p/>
+ *
+ * HLOOKUP finds a column in a lookup table by the first row value and returns the value from another row.
+ *
+ * <b>Syntax</b>:<br/>
+ * <b>HLOOKUP</b>(<b>lookup_value</b>, <b>table_array</b>, <b>row_index_num</b>, range_lookup)<p/>
+ *
+ * <b>lookup_value</b> The value to be found in the first column of the table array.<br/>
+ * <b>table_array</> An area reference for the lookup data. <br/>
+ * <b>row_index_num</b> a 1 based index specifying which row value of the lookup data will be returned.<br/>
+ * <b>range_lookup</b> If TRUE (default), HLOOKUP finds the largest value less than or equal to
+ * the lookup_value. If FALSE, only exact matches will be considered<br/>
+ *
+ * @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 <tt>AreaEval</tt>
+ *
+ * @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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR 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;
+ }
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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<p/>
+ *
+ * Syntax : <br/>
+ * INDEX ( reference, row_num[, column_num [, area_num]])</br>
+ * INDEX ( array, row_num[, column_num])
+ * <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions">
+ * <tr><th>reference</th><td>typically an area reference, possibly a union of areas</td></tr>
+ * <tr><th>array</th><td>a literal array value (currently not supported)</td></tr>
+ * <tr><th>row_num</th><td>selects the row within the array or area reference</td></tr>
+ * <tr><th>column_num</th><td>selects column within the array or area reference. default is 1</td></tr>
+ * <tr><th>area_num</th><td>used when reference is a union of areas</td></tr>
+ * </table>
+ * <p/>
+ *
+ * @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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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<p/>
+ *
+ * INDIRECT() returns the cell or area reference denoted by the text argument.<p/>
+ *
+ * <b>Syntax</b>:</br>
+ * <b>INDIRECT</b>(<b>ref_text</b>,isA1Style)<p/>
+ *
+ * <b>ref_text</b> a string representation of the desired reference as it would normally be written
+ * in a cell formula.<br/>
+ * <b>isA1Style</b> (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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.<p/>
+ *
+ * LOOKUP finds an index row in a lookup table by the first column value and returns the value from another column.
+ *
+ * <b>Syntax</b>:<br/>
+ * <b>VLOOKUP</b>(<b>lookup_value</b>, <b>lookup_vector</b>, result_vector)<p/>
+ *
+ * <b>lookup_value</b> The value to be found in the lookup vector.<br/>
+ * <b>lookup_vector</> An area reference for the lookup data. <br/>
+ * <b>result_vector</b> Single row or single column area reference from which the result value is chosen.<br/>
+ *
+ * @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());
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <tt>AreaEval</tt>.
+ */
+ public interface ValueVector {
+ ValueEval getItem(int index);
+ int getSize();
+ }
+ /**
+ * Enumeration to support <b>4</b> valued comparison results.<p/>
+ * 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.<p/>
+ *
+ * A simple int might have done the same job, but there is risk in confusion with the well
+ * known <tt>Comparable.compareTo()</tt> and <tt>Comparator.compare()</tt> 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 <tt>CompareResult</tt>: <tt>LESS_THAN</tt>, <tt>EQUAL</tt>,
+ * <tt>GREATER_THAN</tt> or <tt>TYPE_MISMATCH</tt>
+ */
+ 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 (<b>col_index_num</b>
+ * or <b>row_index_num</b> respectively).<br>
+ * Sample behaviour:
+ * <table border="0" cellpadding="1" cellspacing="2" summary="Sample behaviour">
+ * <tr><th>Input Return</th><th>Value </th><th>Thrown Error</th></tr>
+ * <tr><td>5</td><td>4</td><td> </td></tr>
+ * <tr><td>2.9</td><td>2</td><td> </td></tr>
+ * <tr><td>"5"</td><td>4</td><td> </td></tr>
+ * <tr><td>"2.18e1"</td><td>21</td><td> </td></tr>
+ * <tr><td>"-$2"</td><td>-3</td><td>*</td></tr>
+ * <tr><td>FALSE</td><td>-1</td><td>*</td></tr>
+ * <tr><td>TRUE</td><td>0</td><td> </td></tr>
+ * <tr><td>"TRUE"</td><td> </td><td>#REF!</td></tr>
+ * <tr><td>"abc"</td><td> </td><td>#REF!</td></tr>
+ * <tr><td>""</td><td> </td><td>#REF!</td></tr>
+ * <tr><td><blank></td><td> </td><td>#VALUE!</td></tr>
+ * </table><br/>
+ *
+ * * 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 (<b>range_lookup</b>) 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<vector[newMid]),
+ // this execution path only moves highIx it down as far as newMid, not midIx,
+ // which would be more efficient.
+ bsi.narrowSearch(newMid, cr.isLessThan());
+ return -1;
+ }
+ }
+ /**
+ * Once the binary search has found a single match, (V/H)LOOKUP steps one by one over subsequent
+ * values to choose the last matching item.
+ */
+ private static int findLastIndexInRunOfEqualValues(LookupValueComparer lookupComparer, ValueVector vector,
+ int firstFoundIndex, int maxIx) {
+ for(int i=firstFoundIndex+1; i<maxIx; i++) {
+ if(!lookupComparer.compareTo(vector.getItem(i)).isEqual()) {
+ return i-1;
+ }
+ }
+ return maxIx - 1;
+ }
+
+ public static LookupValueComparer createLookupComparer(ValueEval lookupValue) throws EvaluationException {
+
+ if (lookupValue instanceof BlankEval) {
+ // blank eval can never be found in a lookup array
+ throw new EvaluationException(ErrorEval.NA);
+ }
+ if (lookupValue instanceof StringEval) {
+ return new StringLookupComparer((StringEval) lookupValue);
+ }
+ if (lookupValue instanceof NumberEval) {
+ return new NumberLookupComparer((NumberEval) lookupValue);
+ }
+ if (lookupValue instanceof BoolEval) {
+ return new BooleanLookupComparer((BoolEval) lookupValue);
+ }
+ throw new IllegalArgumentException("Bad lookup value type (" + lookupValue.getClass().getName() + ")");
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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 Lower 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.toLowerCase());
+ }
+
+ return retval;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.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;
+import org.apache.poi.hssf.record.formula.functions.LookupUtils.CompareResult;
+import org.apache.poi.hssf.record.formula.functions.LookupUtils.LookupValueComparer;
+
+/**
+ * Implementation for the MATCH() Excel function.<p/>
+ *
+ * <b>Syntax:</b><br/>
+ * <b>MATCH</b>(<b>lookup_value</b>, <b>lookup_array</b>, match_type)<p/>
+ *
+ * Returns a 1-based index specifying at what position in the <b>lookup_array</b> the specified
+ * <b>lookup_value</b> is found.<p/>
+ *
+ * Specific matching behaviour can be modified with the optional <b>match_type</b> parameter.
+ *
+ * <table border="0" cellpadding="1" cellspacing="0" summary="match_type parameter description">
+ * <tr><th>Value</th><th>Matching Behaviour</th></tr>
+ * <tr><td>1</td><td>(default) find the largest value that is less than or equal to lookup_value.
+ * The lookup_array must be in ascending <i>order</i>*.</td></tr>
+ * <tr><td>0</td><td>find the first value that is exactly equal to lookup_value.
+ * The lookup_array can be in any order.</td></tr>
+ * <tr><td>-1</td><td>find the smallest value that is greater than or equal to lookup_value.
+ * The lookup_array must be in descending <i>order</i>*.</td></tr>
+ * </table>
+ *
+ * * Note regarding <i>order</i> - For the <b>match_type</b> 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.<br>
+ * The (ascending) sort order expected by MATCH() is:<br/>
+ * numbers (low to high), strings (A to Z), boolean (FALSE to TRUE)<br/>
+ * 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<lookupRange.length; i++) {
+ CompareResult cmp = lookupComparer.compareTo(lookupRange[i]);
+ if(cmp.isEqual()) {
+ return i;
+ }
+ if(cmp.isGreaterThan()) {
+ if(i<1) {
+ throw new EvaluationException(ErrorEval.NA);
+ }
+ return i-1;
+ }
+ }
+
+ throw new EvaluationException(ErrorEval.NA);
+ }
+
+ private static LookupValueComparer createLookupComparer(ValueEval lookupValue, boolean matchExact) throws EvaluationException {
+ if (matchExact && lookupValue instanceof StringEval) {
+ String stringValue = ((StringEval) lookupValue).getStringValue();
+ if(isLookupValueWild(stringValue)) {
+ throw new RuntimeException("Wildcard lookup values '" + stringValue + "' not supported yet");
+ }
+
+ }
+ return LookupUtils.createLookupComparer(lookupValue);
+ }
+
+ private static boolean isLookupValueWild(String stringValue) {
+ if(stringValue.indexOf('?') >=0 || stringValue.indexOf('*') >=0) {
+ return true;
+ }
+ return false;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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.
+ * <p>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.
+ * <p>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.
+ * <p>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.
+ * <p>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.
+ * <p>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.
+ * <p>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
+ * <br/>
+ * If d > 0, returns short 1
+ * <br/>
+ * If d == 0, returns short 0
+ * <p> 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<iSize; i++) {
+ sum += values[i];
+ }
+ ave = sum / values.length;
+ return ave;
+ }
+
+
+ /**
+ * sum of all values
+ * @param values
+ */
+ public static double sum(double[] values) {
+ double sum = 0;
+ for (int i=0, iSize=values.length; i<iSize; i++) {
+ sum += values[i];
+ }
+ return sum;
+ }
+
+ /**
+ * sum of squares of all values
+ * @param values
+ */
+ public static double sumsq(double[] values) {
+ double sumsq = 0;
+ for (int i=0, iSize=values.length; i<iSize; i++) {
+ sumsq += values[i]*values[i];
+ }
+ return sumsq;
+ }
+
+
+ /**
+ * product of all values
+ * @param values
+ */
+ public static double product(double[] values) {
+ double product = 0;
+ if (values!=null && values.length > 0) {
+ product = 1;
+ for (int i=0, iSize=values.length; i<iSize; i++) {
+ product *= values[i];
+ }
+ }
+ return product;
+ }
+
+ /**
+ * min of all values. If supplied array is zero length,
+ * Double.POSITIVE_INFINITY is returned.
+ * @param values
+ */
+ public static double min(double[] values) {
+ double min = Double.POSITIVE_INFINITY;
+ for (int i=0, iSize=values.length; i<iSize; i++) {
+ min = Math.min(min, values[i]);
+ }
+ return min;
+ }
+
+ /**
+ * min of all values. If supplied array is zero length,
+ * Double.NEGATIVE_INFINITY is returned.
+ * @param values
+ */
+ public static double max(double[] values) {
+ double max = Double.NEGATIVE_INFINITY;
+ for (int i=0, iSize=values.length; i<iSize; i++) {
+ max = Math.max(max, values[i]);
+ }
+ return max;
+ }
+
+ /**
+ * Note: this function is different from java.lang.Math.floor(..).
+ * <p>
+ * When n and s are "valid" arguments, the returned value is: Math.floor(n/s) * s;
+ * <br/>
+ * n and s are invalid if any of following conditions are true:
+ * <ul>
+ * <li>s is zero</li>
+ * <li>n is negative and s is positive</li>
+ * <li>n is positive and s is negative</li>
+ * </ul>
+ * 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(..).
+ * <p>
+ * When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s;
+ * <br/>
+ * n and s are invalid if any of following conditions are true:
+ * <ul>
+ * <li>s is zero</li>
+ * <li>n is negative and s is positive</li>
+ * <li>n is positive and s is negative</li>
+ * </ul>
+ * 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;
+ }
+
+ /**
+ * <br/> for all n >= 1; factorial n = n * (n-1) * (n-2) * ... * 1
+ * <br/> else if n == 0; factorial n = 1
+ * <br/> else if n < 0; factorial n = Double.NaN
+ * <br/> 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.
+ * <br/> The result has the sign of the divisor.
+ * <br/> Examples:
+ * <ul>
+ * <li>mod(3.4, 2) = 1.4</li>
+ * <li>mod(-3.4, 2) = 0.6</li>
+ * <li>mod(-3.4, -2) = -1.4</li>
+ * <li>mod(3.4, -2) = -0.6</li>
+ * </ul>
+ * 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<arrlen; j++) {
+ double t = 1;
+ for (int i=0; i<narr; i++) {
+ t *= arrays[i][j];
+ }
+ d += t;
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException ae) {
+ d = Double.NaN;
+ }
+
+ return d;
+ }
+
+ /**
+ * returns the sum of difference of squares of corresponding double
+ * value in each subarray: ie. sigma (xarr[i]^2-yarr[i]^2)
+ * <br/>
+ * 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<iSize; i++) {
+ d += (xarr[i] + yarr[i]) * (xarr[i] - yarr[i]);
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException ae) {
+ d = Double.NaN;
+ }
+
+ return d;
+ }
+
+ /**
+ * returns the sum of sum of squares of corresponding double
+ * value in each subarray: ie. sigma (xarr[i]^2 + yarr[i]^2)
+ * <br/>
+ * 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<iSize; i++) {
+ d += (xarr[i] * xarr[i]) + (yarr[i] * yarr[i]);
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException ae) {
+ d = Double.NaN;
+ }
+
+ return d;
+ }
+
+
+ /**
+ * returns the sum of squares of difference of corresponding double
+ * value in each subarray: ie. sigma ( (xarr[i]-yarr[i])^2 )
+ * <br/>
+ * 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<iSize; i++) {
+ double t = (xarr[i] - yarr[i]);
+ d += t * t;
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException ae) {
+ d = Double.NaN;
+ }
+
+ return d;
+ }
+
+ /**
+ * returns the total number of combinations possible when
+ * k items are chosen out of total of n items. If the number
+ * is too large, loss of precision may occur (since returned
+ * value is double). If the returned value is larger than
+ * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned.
+ * If either of the parameters is negative, Double.NaN is returned.
+ * @param n
+ * @param k
+ */
+ public static double nChooseK(int n, int k) {
+ double d = 1;
+ if (n<0 || k<0 || n<k) {
+ d= Double.NaN;
+ }
+ else {
+ int minnk = Math.min(n-k, k);
+ int maxnk = Math.max(n-k, k);
+ for (int i=maxnk; i<n; i++) {
+ d *= i+1;
+ }
+ d /= factorial(minnk);
+ }
+
+ return d;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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 Max 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.max(values) : 0;
+ retval = (Double.isNaN(d) || Double.isInfinite(d))
+ ? (ValueEval) ErrorEval.NUM_ERROR
+ : new NumberEval(d);
+ }
+
+ return retval;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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<br/> MID returns a specific number of
+ * characters from a text string, starting at the specified position.<p/>
+ *
+ * <b>Syntax<b>:<br/> <b>MID</b>(<b>text</b>, <b>start_num</b>,
+ * <b>num_chars</b>)<br/>
+ *
+ * @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
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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 <code>null</code>.
+ *
+ * @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; i<iSize; i++) {
+ double[] temp = getNumberArray(operands[i], srcRow, srcCol);
+ if (temp == null) {
+ return null; // error occurred.
+ }
+ retval.add(temp);
+ }
+ return retval.toArray();
+ }
+
+ /**
+ * Same as getNumberArray(Eval[], int, short) except that this
+ * takes Eval instead of Eval[].
+ * @param operand
+ * @param srcRow
+ * @param srcCol
+ */
+ protected double[] getNumberArray(Eval operand, int srcRow, short srcCol) {
+
+ if (operand instanceof AreaEval) {
+ AreaEval ae = (AreaEval) operand;
+ ValueEval[] values = ae.getValues();
+ DoubleList retval = new DoubleList();
+ for (int j=0, jSize=values.length; j<jSize; j++) {
+ /*
+ * TODO: For an AreaEval, we are constructing a RefEval
+ * per element.
+ * For now this is a tempfix solution since this may
+ * require a more generic fix at the level of
+ * HSSFFormulaEvaluator where we store an array
+ * of RefEvals as the "values" array.
+ */
+ RefEval re = new Ref2DEval(null, values[j]);
+ ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol);
+
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval nve = (NumericValueEval) ve;
+ retval.add(nve.getNumberValue());
+ }
+ else if (ve instanceof BlankEval) {
+ // note - blanks are ignored, so returned array will be smaller.
+ }
+ else {
+ return null; // indicate to calling subclass that error occurred
+ }
+ }
+ return retval.toArray();
+ }
+
+ // for ValueEvals other than AreaEval
+ ValueEval ve = singleOperandEvaluate(operand, srcRow, srcCol);
+
+ if (ve instanceof NumericValueEval) {
+ NumericValueEval nve = (NumericValueEval) ve;
+ return new double[] { nve.getNumberValue(), };
+ }
+
+ if (ve instanceof BlankEval) {
+ // ignore blanks
+ return EMPTY_DOUBLE_ARRAY;
+ }
+ return null;
+ }
+
+ /**
+ * Ensures that a two dimensional array has all sub-arrays present and the same length
+ * @return <code>false</code> 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<outerMax; i++) { // note - 'i=1' start at second sub-array
+ double[] subArr = values[i];
+ if (subArr == null) {
+ return false;
+ }
+ if (innerMax != subArr.length) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class N extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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;
+
+/**
+ * Implementation of Excel function NA()
+ *
+ * @author Josh Micich
+ */
+public final class Na implements Function {
+
+ public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
+ return ErrorEval.NA;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Names extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Negbinomdist extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Normdist extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Norminv extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Normsdist extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Normsinv extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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.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.RefEval;
+import org.apache.poi.hssf.record.formula.eval.StringEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+
+
+/**
+ * @author Amol S. Deshmukh < amol at apache dot org >
+ * The NOT boolean function. Returns negation of specified value
+ * (treated as a boolean). If the specified arg is a number,
+ * then it is true <=> '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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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()<p/>
+ *
+ * OFFSET returns an area reference that is a specified number of rows and columns from a
+ * reference cell or area.<p/>
+ *
+ * <b>Syntax</b>:<br/>
+ * <b>OFFSET</b>(<b>reference</b>, <b>rows</b>, <b>cols</b>, height, width)<p/>
+ * <b>reference</b> is the base reference.<br/>
+ * <b>rows</b> is the number of rows up or down from the base reference.<br/>
+ * <b>cols</b> is the number of columns left or right from the base reference.<br/>
+ * <b>height</b> (default same height as base reference) is the row count for the returned area reference.<br/>
+ * <b>width</b> (default same width as base reference) is the column count for the returned area reference.<br/>
+ *
+ * @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.<p/>
+ *
+ * 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. <p/>
+ *
+ * @param translationAmount may be zero negative or positive
+ *
+ * @return the equivalent <tt>LinearOffsetRange</tt> 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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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<iSize; i++) {
+ if (operands[i] instanceof AreaEval) {
+ AreaEval ae = (AreaEval) operands[i];
+ ValueEval[] values = ae.getValues();
+ for (int j=0, jSize=values.length; j<jSize; j++) {
+ ValueEval tempVe = singleOperandEvaluate(values[j], srcRow, srcCol, true);
+ if (tempVe instanceof BoolEval) {
+ b = b || ((BoolEval) tempVe).getBooleanValue();
+ atleastOneNonBlank = true;
+ }
+ else if (tempVe instanceof ErrorEval) {
+ retval = tempVe;
+ break outer;
+ }
+ }
+ }
+ else {
+ ValueEval tempVe = singleOperandEvaluate(operands[i], srcRow, srcCol, false);
+ if (tempVe instanceof BoolEval) {
+ b = b || ((BoolEval) tempVe).getBooleanValue();
+ atleastOneNonBlank = true;
+ }
+ else if (tempVe instanceof ErrorEval) {
+ retval = tempVe;
+ break outer;
+ }
+ }
+ }
+
+ if (!atleastOneNonBlank) {
+ retval = ErrorEval.VALUE_INVALID;
+ }
+
+ if (retval == null) { // if no error
+ retval = b ? BoolEval.TRUE : BoolEval.FALSE;
+ }
+
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Pearson extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Percentile extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Percentrank extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/*
+ * Created on May 15, 2005
+ *
+ */
+package org.apache.poi.hssf.record.formula.functions;
+
+public class Permut extends NotImplementedFunction {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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 Pi implements Function {
+
+ private static final NumberEval PI_EVAL = new NumberEval(Math.PI);
+
+ public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
+ ValueEval retval;
+ switch (operands.length) {
+ default:
+ retval = ErrorEval.VALUE_INVALID;
+ break;
+ case 0:
+ retval = PI_EVAL;
+ }
+ return retval;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.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.ValueEval;
+
+/**
+ * Implementation for the PMT() Excel function.<p/>
+ *
+ * <b>Syntax:</b><br/>
+ * <b>PMT</b>(<b>rate</b>, <b>nper</b>, <b>pv</b>, fv, type)<p/>
+ *
+ * Returns the constant repayment amount required for a loan assuming a constant interest rate.<p/>
+ *
+ * <b>rate</b> the loan interest rate.<br/>
+ * <b>nper</b> the number of loan repayments.<br/>
+ * <b>pv</b> the present value of the future payments (or principle).<br/>
+ * <b>fv</b> the future value (default zero) surplus cash at the end of the loan lifetime.<br/>
+ * <b>type</b> whether payments are due at the beginning(1) or end(0 - default) of each payment period.<br/>
+ *
+ */
+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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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<iSize; i++) {
+ s += v[i];
+ }
+ m = s / v.length;
+ s = 0;
+ for (int i=0, iSize=v.length; i<iSize; i++) {
+ s += Math.abs(v[i]-m);
+ }
+ r = s / v.length;
+ return r;
+ }
+
+ public static double stdev(double[] v) {
+ double r = Double.NaN;
+ if (v!=null && v.length > 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<iSize; i++) {
+ for (int j=i+1, jSize=v.length; j<jSize; j++) {
+ if (v[i] == v[j]) counts[i]++;
+ }
+ }
+ double maxv = 0;
+ int maxc = 0;
+ for (int i=0, iSize=counts.length; i<iSize; i++) {
+ if (counts[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<n; i++) {
+ s += v[i];
+ }
+ m = s / n;
+ s = 0;
+ for (int i=0; i<n; i++) {
+ s += (v[i]- m) * (v[i] - m);
+ }
+
+ r = (n == 1)
+ ? 0
+ : s;
+ }
+ return r;
+ }
+
+ /**
+ * returns the kth largest element in the array. Duplicates
+ * are considered as distinct values. Hence, eg.
+ * for array {1,2,4,3,3} & k=2, returned value is 3.
+ * <br/>
+ * 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.
+ * <br/>
+ * 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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<p/>
+ *
+ * Syntax : <br/>
+ * SUMPRODUCT ( array1[, array2[, array3[, ...]]])
+ * <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions">
+ * <tr><th>array1, ... arrayN </th><td>typically area references,
+ * possibly cell references or scalar values</td></tr>
+ * </table><br/>
+ *
+ * Let A<b>n</b><sub>(<b>i</b>,<b>j</b>)</sub> represent the element in the <b>i</b>th row <b>j</b>th column
+ * of the <b>n</b>th array<br/>
+ * Assuming each array has the same dimensions (W, H), the result is defined as:<br/>
+ * SUMPRODUCT = Σ<sub><b>i</b>: 1..H</sub>
+ * ( Σ<sub><b>j</b>: 1..W</sub>
+ * ( Π<sub><b>n</b>: 1..N</sub>
+ * A<b>n</b><sub>(<b>i</b>,<b>j</b>)</sub>
+ * )
+ * )
+ *
+ * @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; n<maxN; n++) {
+ double val = getScalarValue(evalArgs[n]);
+ term *= val;
+ }
+ return new NumberEval(term);
+ }
+
+ private double getScalarValue(Eval arg) throws EvalEx {
+
+ Eval eval;
+ if (arg instanceof RefEval) {
+ RefEval re = (RefEval) arg;
+ eval = re.getInnerValueEval();
+ } else {
+ eval = arg;
+ }
+
+ if (eval == null) {
+ throw new RuntimeException("parameter may not be null");
+ }
+ if (eval instanceof AreaEval) {
+ AreaEval ae = (AreaEval) eval;
+ // an area ref can work as a scalar value if it is 1x1
+ if(!ae.isColumn() || !ae.isRow()) {
+ throw new EvalEx(ErrorEval.VALUE_INVALID);
+ }
+ eval = ae.getValues()[0];
+ }
+
+ if (!(eval instanceof ValueEval)) {
+ throw new RuntimeException("Unexpected value eval class ("
+ + eval.getClass().getName() + ")");
+ }
+
+ return getProductTerm((ValueEval) eval, true);
+ }
+
+ private Eval evaluateAreaSumProduct(Eval[] evalArgs) throws EvalEx {
+ int maxN = evalArgs.length;
+ AreaEval[] args = new AreaEval[maxN];
+ try {
+ System.arraycopy(evalArgs, 0, args, 0, maxN);
+ } catch (ArrayStoreException e) {
+ // one of the other args was not an AreaRef
+ return ErrorEval.VALUE_INVALID;
+ }
+
+
+ AreaEval firstArg = args[0];
+
+ int height = firstArg.getLastRow() - firstArg.getFirstRow() + 1;
+ int width = firstArg.getLastColumn() - firstArg.getFirstColumn() + 1; // TODO - junit
+
+
+
+ double[][][] elements = new double[maxN][][];
+
+ for (int n = 0; n < maxN; n++) {
+ elements[n] = evaluateArea(args[n], height, width);
+ }
+ double acc = 0;
+
+ for(int r=0; r<height; r++) {
+ for(int c=0; c<width; c++) {
+ double term = 1D;
+ for(int n=0; n<maxN; n++) {
+ term *= elements[n][r][c];
+ }
+ acc += term;
+ }
+ }
+
+ return new NumberEval(acc);
+ }
+
+ /**
+ * @return a 2-D array of the specified height and width corresponding to the evaluated cell
+ * values of the specified areaEval
+ * @throws EvalEx if any ErrorEval value was encountered while evaluating the area
+ */
+ private static double[][] evaluateArea(AreaEval areaEval, int height, int width) throws EvalEx {
+ int fr =areaEval.getFirstRow();
+ int fc =areaEval.getFirstColumn();
+
+ // check that height and width match
+ if(areaEval.getLastRow() - fr + 1 != height) {
+ throw new EvalEx(ErrorEval.VALUE_INVALID);
+ }
+ if(areaEval.getLastColumn() - fc + 1 != width) {
+ throw new EvalEx(ErrorEval.VALUE_INVALID);
+ }
+ ValueEval[] values = areaEval.getValues();
+ double[][] result = new double[height][width];
+ for(int r=0; r<height; r++) {
+ for(int c=0; c<width; c++) {
+ ValueEval ve = values[r*width + c];
+ result[r][c] = getProductTerm(ve, false);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Determines a <code>double</code> value for the specified <code>ValueEval</code>.
+ * @param isScalarProduct <code>false</code> for SUMPRODUCTs over area refs.
+ * @throws EvalEx if <code>ve</code> represents an error value.
+ * <p/>
+ * Note - string values and empty cells are interpreted differently depending on
+ * <code>isScalarProduct</code>. 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() + ")");
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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()<p/>
+ *
+ * Calculates the sum of differences of squares in two arrays of the same size.<br/>
+ * <b>Syntax</b>:<br/>
+ * <b>SUMX2MY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
+ *
+ * result = Σ<sub>i: 0..n</sub>(x<sub>i</sub><sup>2</sup>-y<sub>i</sub><sup>2</sup>)
+ *
+ * @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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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()<p/>
+ *
+ * Calculates the sum of squares in two arrays of the same size.<br/>
+ * <b>Syntax</b>:<br/>
+ * <b>SUMX2PY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
+ *
+ * result = Σ<sub>i: 0..n</sub>(x<sub>i</sub><sup>2</sup>+y<sub>i</sub><sup>2</sup>)
+ *
+ * @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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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()<p/>
+ *
+ * Calculates the sum of squares of differences between two arrays of the same size.<br/>
+ * <b>Syntax</b>:<br/>
+ * <b>SUMXMY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
+ *
+ * result = Σ<sub>i: 0..n</sub>(x<sub>i</sub>-y<sub>i</sub>)<sup>2</sup>
+ *
+ * @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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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();
+ }
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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;
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.<p/>
+ *
+ * VLOOKUP finds a row in a lookup table by the first column value and returns the value from another column.
+ *
+ * <b>Syntax</b>:<br/>
+ * <b>VLOOKUP</b>(<b>lookup_value</b>, <b>table_array</b>, <b>col_index_num</b>, range_lookup)<p/>
+ *
+ * <b>lookup_value</b> The value to be found in the first column of the table array.<br/>
+ * <b>table_array</> An area reference for the lookup data. <br/>
+ * <b>col_index_num</b> a 1 based index specifying which column value of the lookup data will be returned.<br/>
+ * <b>range_lookup</b> If TRUE (default), VLOOKUP finds the largest value less than or equal to
+ * the lookup_value. If FALSE, only exact matches will be considered<br/>
+ *
+ * @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 <tt>AreaEval</tt>
+ *
+ * @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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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<iSize; i++) {
+ Eval xEval = xops[i];
+ Eval yEval = yops[i];
+
+ if (isNumberEval(xEval) && isNumberEval(yEval)) {
+ xResult[count] = getDoubleValue(xEval);
+ yResult[count] = getDoubleValue(yEval);
+ if (Double.isNaN(xResult[count]) || Double.isNaN(xResult[count])) {
+ throw new EvaluationException(ErrorEval.NUM_ERROR);
+ }
+ count++;
+ }
+ }
+
+ return new double[][] {
+ trimToSize(xResult, count),
+ trimToSize(yResult, count),
+ };
+ }
+
+ private static double[][] getValues(Eval argX, Eval argY) throws EvaluationException {
+
+ if (argX instanceof ErrorEval) {
+ throw new EvaluationException((ErrorEval) argX);
+ }
+ if (argY instanceof ErrorEval) {
+ throw new EvaluationException((ErrorEval) argY);
+ }
+
+ Eval[] xEvals;
+ Eval[] yEvals;
+ if (argX instanceof AreaEval) {
+ AreaEval ae = (AreaEval) argX;
+ xEvals = ae.getValues();
+ } else {
+ xEvals = new Eval[] { argX, };
+ }
+
+ if (argY instanceof AreaEval) {
+ AreaEval ae = (AreaEval) argY;
+ yEvals = ae.getValues();
+ } else {
+ yEvals = new Eval[] { argY, };
+ }
+
+ return getNumberArray(xEvals, yEvals);
+ }
+
+ private static double[] trimToSize(double[] arr, int len) {
+ double[] tarr = arr;
+ if (arr.length > 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;
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License 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
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the 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 {
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <tt>HSSFFormulaEvaluator.internalEvaluate()</tt>.
+ * 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.<br/>
+ */
+ 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.<br/>
+ *
+ * In the case of a <code>true</code> return code, the caller should
+ * continue evaluation of the specified cell, and also be sure to call
+ * <tt>endEvaluate()</tt> when complete.<br/>
+ *
+ * In the case of a <code>false</code> return code, the caller should
+ * return an evaluation result of
+ * <tt>ErrorEval.CIRCULAR_REF_ERROR<tt>, and not call <tt>endEvaluate()</tt>.
+ * <br/>
+ * @return <code>true</code> if the specified cell has not been visited yet in the current
+ * evaluation. <code>false</code> 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. <p/>
+ *
+ * Every successful call to <tt>startEvaluate</tt> must be followed by a
+ * call to <tt>endEvaluate</tt> (recommended in a finally block) to enable
+ * proper tracking of which cells are being evaluated at any point in time.<p/>
+ *
+ * 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <tt>EvaluationCycleDetector</tt> instance available to
+ * each thread via a <tt>ThreadLocal</tt> in order to avoid adding a parameter
+ * to a few protected methods within <tt>HSSFFormulaEvaluator</tt>.
+ *
+ * @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
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.
+ * <pre>
+ * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
+ * </pre>
+ * 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:
+ * <pre>
+ * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
+ * </pre>
+ * 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<wb.getNumberOfSheets(); i++) {
+ HSSFSheet sheet = wb.getSheetAt(i);
+ 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);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Returns a CellValue wrapper around the supplied ValueEval instance.
+ * @param eval
+ */
+ protected static CellValue getCellValueForEval(ValueEval eval) {
+ CellValue retval = null;
+ if (eval != null) {
+ if (eval instanceof NumberEval) {
+ NumberEval ne = (NumberEval) eval;
+ retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC);
+ retval.setNumberValue(ne.getNumberValue());
+ }
+ else if (eval instanceof BoolEval) {
+ BoolEval be = (BoolEval) eval;
+ retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN);
+ retval.setBooleanValue(be.getBooleanValue());
+ }
+ else if (eval instanceof StringEval) {
+ StringEval ne = (StringEval) eval;
+ retval = new CellValue(HSSFCell.CELL_TYPE_STRING);
+ retval.setStringValue(ne.getStringValue());
+ }
+ else if (eval instanceof BlankEval) {
+ retval = new CellValue(HSSFCell.CELL_TYPE_BLANK);
+ }
+ else if (eval instanceof ErrorEval) {
+ retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
+ retval.setErrorValue((byte)((ErrorEval)eval).getErrorCode());
+// retval.setRichTextStringValue(new HSSFRichTextString("#An error occurred. check cell.getErrorCode()"));
+ }
+ else {
+ retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
+ }
+ }
+ return retval;
+ }
+
+ /**
+ * Dev. Note: Internal evaluate must be passed only a formula cell
+ * else a runtime exception will be thrown somewhere inside the method.
+ * (Hence this is a private method.)
+ */
+ private static ValueEval internalEvaluate(HSSFCell srcCell, HSSFRow srcRow, HSSFSheet sheet, HSSFWorkbook workbook) {
+ int srcRowNum = srcRow.getRowNum();
+ short srcColNum = srcCell.getCellNum();
+
+
+ EvaluationCycleDetector tracker = EvaluationCycleDetectorManager.getTracker();
+
+ if(!tracker.startEvaluate(workbook, sheet, srcRowNum, srcColNum)) {
+ return ErrorEval.CIRCULAR_REF_ERROR;
+ }
+ try {
+ return evaluateCell(workbook, sheet, srcRowNum, srcColNum, srcCell.getCellFormula());
+ } finally {
+ tracker.endEvaluate(workbook, sheet, srcRowNum, srcColNum);
+ }
+ }
+ private static ValueEval evaluateCell(HSSFWorkbook workbook, HSSFSheet sheet,
+ int srcRowNum, short srcColNum, String cellFormulaText) {
+ FormulaParser parser = new FormulaParser(cellFormulaText, workbook.getWorkbook());
+ parser.parse();
+ Ptg[] ptgs = parser.getRPNPtg();
+ // -- parsing over --
+
+
+ Stack stack = new Stack();
+ for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
+
+ // since we don't know how to handle these yet :(
+ Ptg ptg = ptgs[i];
+ if (ptg instanceof ControlPtg) { continue; }
+ if (ptg instanceof MemErrPtg) { continue; }
+ if (ptg instanceof MissingArgPtg) { continue; }
+ if (ptg instanceof NamePtg) {
+ // named ranges, macro functions
+ NamePtg namePtg = (NamePtg) ptg;
+ stack.push(new NameEval(namePtg.getIndex()));
+ continue;
+ }
+ if (ptg instanceof NameXPtg) {
+ // TODO - external functions
+ continue;
+ }
+ if (ptg instanceof UnknownPtg) { continue; }
+
+ if (ptg instanceof OperationPtg) {
+ OperationPtg optg = (OperationPtg) ptg;
+
+ // parens can be ignored since we have RPN tokens
+ if (optg instanceof ParenthesisPtg) { continue; }
+ if (optg instanceof AttrPtg) { continue; }
+ if (optg instanceof UnionPtg) { continue; }
+
+ OperationEval operation = OperationEvaluatorFactory.create(optg);
+
+ int numops = operation.getNumberOfOperands();
+ Eval[] ops = new Eval[numops];
+
+ // storing the ops in reverse order since they are popping
+ for (int j = numops - 1; j >= 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 <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
+ * <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
+ */
+ 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 <br/>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("<ptg-group>");
+ for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
+ System.out.println("<ptg>");
+ System.out.println(ptgs[i]);
+ if (ptgs[i] instanceof OperationPtg) {
+ System.out.println("numoperands: " + ((OperationPtg) ptgs[i]).getNumberOfOperands());
+ }
+ System.out.println("</ptg>");
+ }
+ System.out.println("</ptg-group>");
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <tt>OperationEval</tt> instances to help evaluate <tt>OperationPtg</tt>
+ * 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;
+ }
+}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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;
-
-/**
- * <p>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.</p>
- * <p>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<rowrec.getRowNumber(); i++) {
- MissingRowDummyRecord dr = new MissingRowDummyRecord(i);
- childListener.processRecord(dr);
- }
- }
-
- // Record this as the last row we saw
- lastSeenRow = rowrec.getRowNumber();
- break;
-
-
- // These are all the "cell" records
-
- case BlankRecord.sid:
- BlankRecord brec = (BlankRecord) record;
- thisRow = brec.getRow();
- thisColumn = brec.getColumn();
- break;
- case BoolErrRecord.sid:
- BoolErrRecord berec = (BoolErrRecord) record;
- thisRow = berec.getRow();
- thisColumn = berec.getColumn();
- break;
- case FormulaRecord.sid:
- FormulaRecord frec = (FormulaRecord) record;
- thisRow = frec.getRow();
- thisColumn = frec.getColumn();
- break;
- case LabelRecord.sid:
- LabelRecord lrec = (LabelRecord) record;
- thisRow = lrec.getRow();
- thisColumn = lrec.getColumn();
- //System.out.println("Cell found containing String "
- // + " at row " + lrec.getRow() + " and column " + lrec.getColumn());
- break;
- case LabelSSTRecord.sid:
- LabelSSTRecord lsrec = (LabelSSTRecord) record;
- thisRow = lsrec.getRow();
- thisColumn = lsrec.getColumn();
- //System.out.println("Cell found containing String "
- // + " at row " + lsrec.getRow() + " and column " + lsrec.getColumn());
- break;
- case NoteRecord.sid:
- NoteRecord nrec = (NoteRecord) record;
- thisRow = nrec.getRow();
- thisColumn = nrec.getColumn();
- break;
- case NumberRecord.sid:
- NumberRecord numrec = (NumberRecord) record;
- thisRow = numrec.getRow();
- thisColumn = numrec.getColumn();
- //System.out.println("Cell found with value " + numrec.getValue()
- // + " at row " + numrec.getRow() + " and column " + numrec.getColumn());
- break;
- case RKRecord.sid:
- RKRecord rkrec = (RKRecord) record;
- thisRow = rkrec.getRow();
- thisColumn = rkrec.getColumn();
- break;
- default:
- //System.out.println(record.getClass());
- break;
- }
-
- // Do we need to fire dummy end-of-row records?
- if(thisRow != lastSeenRow) {
- for(int i=lastSeenRow; i<thisRow; i++) {
- int cols = -1;
- if(i == lastSeenRow) {
- cols = lastSeenColumn;
- }
- LastCellOfRowDummyRecord r = new LastCellOfRowDummyRecord(i, cols);
- childListener.processRecord(r);
- }
- }
- // If we've finished with the columns, then fire the final
- // dummy end-of-row record
- if(lastSeenRow != -1 && lastSeenColumn != -1 && thisRow == -1) {
- LastCellOfRowDummyRecord r = new LastCellOfRowDummyRecord(lastSeenRow, lastSeenColumn);
- childListener.processRecord(r);
-
- lastSeenRow = -1;
- lastSeenColumn = -1;
- }
-
- // If we've moved onto a new row, the ensure we re-set
- // the column counter
- if(thisRow != lastSeenRow) {
- lastSeenColumn = -1;
- }
-
- // Do we need to fire dummy cell records?
- if(lastSeenColumn != (thisColumn-1)) {
- for(int i=lastSeenColumn+1; i<thisColumn; i++) {
- MissingCellDummyRecord r = new MissingCellDummyRecord(thisRow, i);
- childListener.processRecord(r);
- }
- }
-
- // Update cell and row counts if doing cells
- if(thisColumn != -1) {
- lastSeenRow = thisRow;
- lastSeenColumn = thisColumn;
- }
-
- childListener.processRecord(record);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.dummyrecord;
-
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * A dummy record to indicate that we've now had the last
- * cell record for this row.
- */
-public class LastCellOfRowDummyRecord extends Record {
- private int row;
- private int lastColumnNumber;
-
- public LastCellOfRowDummyRecord(int row, int lastColumnNumber) {
- this.row = row;
- this.lastColumnNumber = lastColumnNumber;
- }
-
- /**
- * Returns the (0 based) number of the row we are
- * currently working on.
- */
- public int getRow() { return row; }
- /**
- * Returns the (0 based) number of the last column
- * seen for this row. You should have already been
- * called with that record.
- * This is -1 in the case of there being no columns
- * for the row.
- */
- public int getLastColumnNumber() { return lastColumnNumber; }
-
- protected void fillFields(RecordInputStream in) {
- }
- public short getSid() {
- return -1;
- }
- public int serialize(int offset, byte[] data) {
- return -1;
- }
- protected void validateSid(short id) {
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.dummyrecord;
-
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * A dummy record for when we're missing a cell in a row,
- * but still want to trigger something
- */
-public class MissingCellDummyRecord extends Record {
- private int row;
- private int column;
-
- public MissingCellDummyRecord(int row, int column) {
- this.row = row;
- this.column = column;
- }
-
- protected void fillFields(RecordInputStream in) {
- }
- public short getSid() {
- return -1;
- }
- public int serialize(int offset, byte[] data) {
- return -1;
- }
- protected void validateSid(short id) {
- }
-
- public int getRow() { return row; }
- public int getColumn() { return column; }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.dummyrecord;
-
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.RecordInputStream;
-
-/**
- * A dummy record for when we're missing a row, but still
- * want to trigger something
- */
-public class MissingRowDummyRecord extends Record {
- private int rowNumber;
-
- public MissingRowDummyRecord(int rowNumber) {
- this.rowNumber = rowNumber;
- }
-
- protected void fillFields(RecordInputStream in) {
- }
- public short getSid() {
- return -1;
- }
- public int serialize(int offset, byte[] data) {
- return -1;
- }
- protected void validateSid(short id) {
- }
-
- public int getRowNumber() {
- return rowNumber;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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.AddPtg;
-import org.apache.poi.hssf.record.formula.Ptg;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- * This is a documentation of the observed behaviour of
- * the '+' operator in Excel:
- * <ol>
- * <li> 1+TRUE = 2
- * <li> 1+FALSE = 1
- * <li> 1+"true" = #VALUE!
- * <li> 1+"1" = 2
- * <li> 1+A1 = #VALUE if A1 contains "1"
- * <li> 1+A1 = 2 if A1 contains ="1"
- * <li> 1+A1 = 2 if A1 contains TRUE or =TRUE
- * <li> 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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);
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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() {
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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:<br/>
- * <code>(b ? BoolEval.TRUE : BoolEval.FALSE)</code>
- * @return a <tt>BoolEval</tt> instance representing <tt>b</tt>.
- */
- 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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;
-
- /** <b>#NULL!</b> - Intersection of two cell ranges is empty */
- public static final ErrorEval NULL_INTERSECTION = new ErrorEval(EC.ERROR_NULL);
- /** <b>#DIV/0!</b> - Division by zero */
- public static final ErrorEval DIV_ZERO = new ErrorEval(EC.ERROR_DIV_0);
- /** <b>#VALUE!</b> - Wrong type of operand */
- public static final ErrorEval VALUE_INVALID = new ErrorEval(EC.ERROR_VALUE);
- /** <b>#REF!</b> - Illegal or deleted cell reference */
- public static final ErrorEval REF_INVALID = new ErrorEval(EC.ERROR_REF);
- /** <b>#NAME?</b> - Wrong function or range name */
- public static final ErrorEval NAME_INVALID = new ErrorEval(EC.ERROR_NAME);
- /** <b>#NUM!</b> - Value range overflow */
- public static final ErrorEval NUM_ERROR = new ErrorEval(EC.ERROR_NUM);
- /** <b>#N/A</b> - 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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 {
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <i>within</i> operator and function
- * implementations. Note - <tt>OperationEval.evaluate()</tt> and <tt>Function.evaluate()</tt>
- * method signatures do not throw this exception so it cannot propagate outside.<p/>
- *
- * Here is an example coded without <tt>EvaluationException</tt>, to show how it can help:
- * <pre>
- * 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();
- * }
- * // ...
- * }
- * </pre>
- * 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.<br/>
- * Using <tt>EvaluationException</tt> allows the error returning code to be consolidated to one
- * place.<p/>
- * <pre>
- * 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;
- *}
- * </pre>
- * It is not mandatory to use EvaluationException, doing so might give the following advantages:<br/>
- * - Methods can more easily be extracted, allowing for re-use.<br/>
- * - Type management (typecasting etc) is simpler because error conditions have been separated from
- * intermediate calculation values.<br/>
- * - Fewer local variables are required. Local variables can have stronger types.<br/>
- * - 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.<p/>
- *
- * <b>Note</b> - Only standard evaluation errors are represented by <tt>EvaluationException</tt> (
- * 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
-
- /** <b>#VALUE!</b> - Wrong type of operand */
- public static EvaluationException invalidValue() {
- return new EvaluationException(ErrorEval.VALUE_INVALID);
- }
- /** <b>#REF!</b> - Illegal or deleted cell reference */
- public static EvaluationException invalidRef() {
- return new EvaluationException(ErrorEval.REF_INVALID);
- }
- /** <b>#NUM!</b> - Value range overflow */
- public static EvaluationException numberError() {
- return new EvaluationException(ErrorEval.NUM_ERROR);
- }
-
- public ErrorEval getErrorEval() {
- return _errorEval;
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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
- * <tt>AbstractFunctionPtg.field_2_fnc_index</tt> == 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);
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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);
- }
- }
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt> or <tt>BlankEval</tt>.
- * Never <code>null</code> or <tt>ErrorEval</tt>.
- * @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.
- *
- * <table border="1" cellpadding="1" cellspacing="1" summary="sample spreadsheet">
- * <tr><th> </th><th> A </th><th> B </th><th> C </th><th> D </th></tr>
- * <tr><th>1</th><td>15</td><td>20</td><td>25</td><td> </td></tr>
- * <tr><th>2</th><td> </td><td> </td><td> </td><td>200</td></tr>
- * <tr><th>3</th><td> </td><td> </td><td> </td><td>300</td></tr>
- * <tr><th>3</th><td> </td><td> </td><td> </td><td>400</td></tr>
- * </table>
- *
- * If the formula "=1000+A1:B1+D2:D3" is put into the 9 cells from A2 to C4, the spreadsheet
- * will look like this:
- *
- * <table border="1" cellpadding="1" cellspacing="1" summary="sample spreadsheet">
- * <tr><th> </th><th> A </th><th> B </th><th> C </th><th> D </th></tr>
- * <tr><th>1</th><td>15</td><td>20</td><td>25</td><td> </td></tr>
- * <tr><th>2</th><td>1215</td><td>1220</td><td>#VALUE!</td><td>200</td></tr>
- * <tr><th>3</th><td>1315</td><td>1320</td><td>#VALUE!</td><td>300</td></tr>
- * <tr><th>4</th><td>#VALUE!</td><td>#VALUE!</td><td>#VALUE!</td><td>400</td></tr>
- * </table>
- *
- * 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.<p/>
- *
- * The same concept is extended to references across sheets, such that even multi-row,
- * multi-column areas can be useful.<p/>
- *
- * Of course with carefully (or carelessly) chosen parameters, cyclic references can occur and
- * hence this method <b>can</b> throw a 'circular reference' EvaluationException. Note that
- * this method does not attempt to detect cycles. Every cell in the specified Area <tt>ae</tt>
- * has already been evaluated prior to this method call. Any cell (or cell<b>s</b>) part of
- * <tt>ae</tt> that would incur a cyclic reference error if selected by this method, will
- * already have the value <t>ErrorEval.CIRCULAR_REF_ERROR</tt> 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 <code>null</code>. Never
- * <tt>ErrorEval</tt>.
- * @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 <tt>ErrorEval</tt>, and <code>null</code>
- */
- 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.<br/>
- * Value is first coerced to a <tt>double</tt> ( See <tt>coerceValueToDouble()</tt> ).<p/>
- *
- * Excel typically converts doubles to integers by truncating toward negative infinity.<br/>
- * The equivalent java code is:<br/>
- * <code>return (int)Math.floor(d);</code><br/>
- * <b>not</b>:<br/>
- * <code>return (int)d; // wrong - rounds toward zero</code>
- *
- */
- 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 - <tt>BlankEval</tt> is not supported and must be handled by the caller.
- * @param ev must be a <tt>NumberEval</tt>, <tt>StringEval</tt> or <tt>BoolEval</tt>
- * @return actual, parsed or interpreted double value (respectively).
- * @throws EvaluationException(#VALUE!) only if a StringEval is supplied and cannot be parsed
- * as a double (See <tt>parseDouble()</tt> for allowable formats).
- * @throws RuntimeException if the supplied parameter is not <tt>NumberEval</tt>,
- * <tt>StringEval</tt> or <tt>BoolEval</tt>
- */
- 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.<br/>
- * Tolerates currency prefixes, commas, leading and trailing spaces.<p/>
- *
- * Some examples:<br/>
- * " 123 " -> 123.0<br/>
- * ".123" -> 0.123<br/>
- * These not supported yet:<br/>
- * " $ 1,000.00 " -> 1000.0<br/>
- * "$1.25E4" -> 12500.0<br/>
- * "5**2" -> 500<br/>
- * "250%" -> 2.5<br/>
- *
- * @param text
- * @return <code>null</code> 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 <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>, or <tt>BlankEval</tt>
- * @return the converted string value. never <code>null</code>
- */
- 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() + ")");
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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();
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 '%'. <p/>
- * @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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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 <code>null</code>, possibly empty string.
- */
- String getStringValue();
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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<iSize; i++) {
- if (operands[i] instanceof AreaEval) {
- AreaEval ae = (AreaEval) operands[i];
- ValueEval[] values = ae.getValues();
- for (int j=0, jSize=values.length; j<jSize; j++) {
- ValueEval tempVe = singleOperandEvaluate(values[j], srcRow, srcCol, true);
- if (tempVe instanceof BoolEval) {
- b = b && ((BoolEval) tempVe).getBooleanValue();
- atleastOneNonBlank = true;
- }
- else if (tempVe instanceof ErrorEval) {
- retval = tempVe;
- break outer;
- }
- }
- }
- else {
- ValueEval tempVe = singleOperandEvaluate(operands[i], srcRow, srcCol, false);
- if (tempVe instanceof BoolEval) {
- b = b && ((BoolEval) tempVe).getBooleanValue();
- atleastOneNonBlank = true;
- }
- else if (tempVe instanceof StringEval) {
- retval = ErrorEval.VALUE_INVALID;
- }
- else if (tempVe instanceof ErrorEval) {
- retval = tempVe;
- break outer;
- }
- }
- }
-
- if (!atleastOneNonBlank) {
- retval = ErrorEval.VALUE_INVALID;
- }
-
- if (retval == null) { // if no error
- retval = b ? BoolEval.TRUE : BoolEval.FALSE;
- }
-
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Areas extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Argument extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Asc extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public class Asin extends NumericFunction {
-
- public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- double d = 0;
- ValueEval retval = null;
-
- switch (operands.length) {
- default:
- retval = ErrorEval.VALUE_INVALID;
- break;
- case 1:
- ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- NumericValueEval ne = (NumericValueEval) ve;
- d = ne.getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.NUM_ERROR;
- }
- }
-
- if (retval == null) {
- d = Math.asin(d);
- retval = (Double.isNaN(d))
- ? (ValueEval) ErrorEval.NUM_ERROR
- : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- * Support for hyperbolic trig functions was added as a part of
- * Java distribution only in JDK1.5. This class uses custom
- * naive implementation based on formulas at:
- * http://www.math2.org/math/trig/hyperbolics.htm
- * These formulas seem to agree with excel's implementation.
- *
- */
-public class Asinh extends NumericFunction {
-
-
- public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- double d = 0;
- ValueEval retval = null;
-
- switch (operands.length) {
- default:
- retval = ErrorEval.VALUE_INVALID;
- break;
- case 1:
- ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- NumericValueEval ne = (NumericValueEval) ve;
- d = ne.getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.NUM_ERROR;
- }
- }
-
- if (retval == null) {
- d = MathX.asinh(d);
- retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public class Atan extends NumericFunction {
-
- public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- double d = 0;
- ValueEval retval = null;
-
- switch (operands.length) {
- default:
- retval = ErrorEval.VALUE_INVALID;
- break;
- case 1:
- ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- NumericValueEval ne = (NumericValueEval) ve;
- d = ne.getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.NUM_ERROR;
- }
- }
-
- if (retval == null) {
- d = Math.atan(d);
- retval = (Double.isNaN(d))
- ? (ValueEval) ErrorEval.NUM_ERROR
- : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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 Atan2 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 = (d0 == d1 && d1 == 0)
- ? Double.NaN
- : Math.atan2(d1, d0);
- retval = (Double.isNaN(d) || Double.isInfinite(d))
- ? (ValueEval) ErrorEval.NUM_ERROR
- : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- * Support for hyperbolic trig functions was added as a part of
- * Java distribution only in JDK1.5. This class uses custom
- * naive implementation based on formulas at:
- * http://www.math2.org/math/trig/hyperbolics.htm
- * These formulas seem to agree with excel's implementation.
- *
- */
-public class Atanh extends NumericFunction {
-
- public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- double d = 0;
- ValueEval retval = null;
-
- switch (operands.length) {
- default:
- retval = ErrorEval.VALUE_INVALID;
- break;
- case 1:
- ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- NumericValueEval ne = (NumericValueEval) ve;
- d = ne.getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.NUM_ERROR;
- }
- }
-
- if (retval == null) {
- d = MathX.atanh(d);
- retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.NUM_ERROR : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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 Avedev 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.avedev(values);
- retval = (Double.isNaN(d) || Double.isInfinite(d))
- ? (ValueEval) ErrorEval.NUM_ERROR
- : new NumberEval(d);
- }
-
- return retval;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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 Average 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 = MathX.average(values);
- retval = (Double.isNaN(d) || Double.isInfinite(d))
- ? (ValueEval) ErrorEval.NUM_ERROR
- : new NumberEval(d);
- }
-
- return retval;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public class Averagea extends NotImplementedFunction {
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Betadist extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Betainv extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Binomdist extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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.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;
-
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- * Here are the general rules concerning Boolean functions:
- * <ol>
- * <li> Blanks are not either true or false
- * <li> Strings are not either true or false (even strings "true"
- * or "TRUE" or "0" etc.)
- * <li> Numbers: 0 is false. Any other number is TRUE.
- * <li> References are evaluated and above rules apply.
- * <li> Areas: Individual cells in area are evaluated and checked to
- * see if they are blanks, strings etc.
- * </ol>
- */
-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;
-
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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<iSize; i++) {
- ValueEval ve = singleOperandEvaluate(operands[i], srcCellRow, srcCellCol);
- if (ve instanceof StringValueEval) {
- StringValueEval sve = (StringValueEval) ve;
- sb.append(sve.getStringValue());
- }
- else if (ve instanceof BlankEval) {}
- else {
- retval = ErrorEval.VALUE_INVALID;
- break;
- }
- }
-
- if (retval == null) {
- retval = new StringEval(sb.toString());
- }
-
- return retval;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Confidence extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Correl extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public class Cos extends NumericFunction {
-
- public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- double d = 0;
- ValueEval retval = null;
-
- switch (operands.length) {
- default:
- retval = ErrorEval.VALUE_INVALID;
- break;
- case 1:
- ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- NumericValueEval ne = (NumericValueEval) ve;
- d = ne.getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.NUM_ERROR;
- }
- }
-
- if (retval == null) {
- d = Math.cos(d);
- retval = (Double.isNaN(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 6, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-import org.apache.poi.hssf.record.formula.eval.BlankEval;
-import org.apache.poi.hssf.record.formula.eval.ErrorEval;
-import org.apache.poi.hssf.record.formula.eval.Eval;
-import org.apache.poi.hssf.record.formula.eval.NumberEval;
-import org.apache.poi.hssf.record.formula.eval.NumericValueEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * @author Amol S. Deshmukh < amolweb at ya hoo dot com >
- *
- */
-public class Cosh extends NumericFunction {
-
- public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- double d = 0;
- ValueEval retval = null;
-
- switch (operands.length) {
- default:
- retval = ErrorEval.VALUE_INVALID;
- break;
- case 1:
- ValueEval ve = singleOperandEvaluate(operands[0], srcRow, srcCol);
- if (ve instanceof NumericValueEval) {
- NumericValueEval ne = (NumericValueEval) ve;
- d = ne.getNumberValue();
- }
- else if (ve instanceof BlankEval) {
- // do nothing
- }
- else {
- retval = ErrorEval.NUM_ERROR;
- }
- }
-
- if (retval == null) {
- d = MathX.cosh(d);
- retval = (Double.isNaN(d) || Double.isInfinite(d)) ? (ValueEval) ErrorEval.VALUE_INVALID : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Count extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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.RefEval;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-/**
- * Counts the number of cells that contain data within the list of arguments.
- *
- * Excel Syntax
- * COUNTA(value1,value2,...)
- * Value1, value2, ... are 1 to 30 arguments representing the values or ranges to be counted.
- *
- * @author Josh Micich
- */
-public final class Counta implements Function {
-
- public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
- int nArgs = args.length;
- if (nArgs < 1) {
- // too few arguments
- return ErrorEval.VALUE_INVALID;
- }
-
- if (nArgs > 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<nArgs; i++) {
- temp += countArg(args[i]);
-
- }
- return new NumberEval(temp);
- }
-
- private static int countArg(Eval eval) {
- if (eval instanceof AreaEval) {
- AreaEval ae = (AreaEval) eval;
- return countAreaEval(ae);
- }
- if (eval instanceof RefEval) {
- RefEval refEval = (RefEval)eval;
- return countValue(refEval.getInnerValueEval());
- }
- if (eval instanceof NumberEval) {
- return 1;
- }
- if (eval instanceof StringEval) {
- return 1;
- }
-
-
- throw new RuntimeException("Unexpected eval type (" + eval.getClass().getName() + ")");
- }
-
- private static int countAreaEval(AreaEval ae) {
-
- int temp = 0;
- ValueEval[] values = ae.getValues();
- for (int i = 0; i < values.length; i++) {
- ValueEval val = values[i];
- if(val == null) {
- // seems to occur. Really we would have expected BlankEval
- continue;
- }
- temp += countValue(val);
-
- }
- return temp;
- }
-
- private static int countValue(ValueEval valueEval) {
-
- if(valueEval == BlankEval.INSTANCE) {
- return 0;
- }
-
- if(valueEval instanceof BlankEval) {
- // wouldn't need this if BlankEval was final
- return 0;
- }
-
- if(valueEval instanceof ErrorEval) {
- // note - error values are counted
- return 1;
- }
- // also empty strings and zeros are counted too
-
- return 1;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Countblank extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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.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;
-
-/**
- * Implementation for the function COUNTIF<p/>
- *
- * Syntax: COUNTIF ( range, criteria )
- * <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions">
- * <tr><th>range </th><td>is the range of cells to be counted based on the criteria</td></tr>
- * <tr><th>criteria</th><td>is used to determine which cells to count</td></tr>
- * </table>
- * <p/>
- *
- * @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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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.
- * <b>Glossary of terms/abbreviations:</b>
- * <br/>
- * <ul>
- * <li><em>FV:</em> Future Value</li>
- * <li><em>PV:</em> Present Value</li>
- * <li><em>NPV:</em> Net Present Value</li>
- * <li><em>PMT:</em> (Periodic) Payment</li>
- *
- * </ul>
- * For more info on the terms/abbreviations please use the references below
- * (hyperlinks are subject to change):
- * </br>Online References:
- * <ol>
- * <li>GNU Emacs Calc 2.02 Manual: http://theory.uwinnipeg.ca/gnu/calc/calc_203.html</li>
- * <li>Yahoo Financial Glossary: http://biz.yahoo.com/f/g/nn.html#y</li>
- * <li>MS Excel function reference: http://office.microsoft.com/en-us/assistance/CH062528251033.aspx</li>
- * </ol>
- * <h3>Implementation Notes:</h3>
- * Symbols used in the formulae that follow:<br/>
- * <ul>
- * <li>p: present value</li>
- * <li>f: future value</li>
- * <li>n: number of periods</li>
- * <li>y: payment (in each period)</li>
- * <li>r: rate</li>
- * <li>^: the power operator (NOT the java bitwise XOR operator!)</li>
- * </ul>
- * [From MS Excel function reference] Following are some of the key formulas
- * that are used in this implementation:
- * <pre>
- * p(1+r)^n + y(1+rt)((1+r)^n-1)/r + f=0 ...{when r!=0}
- * ny + p + f=0 ...{when r=0}
- * </pre>
- */
-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<iSize; i++) {
- npv += cfs[i] / trate;
- trate *= r1;
- }
- return npv;
- }
-
- /**
- *
- * @param r
- * @param n
- * @param p
- * @param f
- * @param t
- */
- public static double pmt(double r, double n, double p, double f, boolean t) {
- double retval = 0;
- if (r == 0) {
- retval = -1*(f+p)/n;
- }
- else {
- double r1 = r + 1;
- retval = ( f + p * Math.pow(r1, n) ) * r
- /
- ((t ? r1 : 1) * (1 - Math.pow(r1, n)));
- }
- return retval;
- }
-
- /**
- *
- * @param r
- * @param y
- * @param p
- * @param f
- * @param t
- */
- public static double nper(double r, double y, double p, double f, boolean t) {
- double retval = 0;
- if (r == 0) {
- retval = -1 * (f + p) / y;
- } else {
- double r1 = r + 1;
- double ryr = (t ? r1 : 1) * y / r;
- double a1 = ((ryr - f) < 0)
- ? Math.log(f - ryr)
- : Math.log(ryr - f);
- double a2 = ((ryr - f) < 0)
- ? Math.log(-p - ryr)
- : Math.log(p + ryr);
- double a3 = Math.log(r1);
- retval = (a1 - a2) / a3;
- }
- return retval;
- }
-
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Find extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Findb extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Finv extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Fisher extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Fisherinv extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Fixed extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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 Floor 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.floor(d0, d1);
- retval = (Double.isNaN(d) || Double.isInfinite(d))
- ? (ValueEval) ErrorEval.NUM_ERROR
- : new NumberEval(d);
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Forecast extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Formulaconvert extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Fpos extends NotImplementedFunction {
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.Eval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-
-
-/**
- * For most Excel functions, involving references ((cell, area), (2d, 3d)), the references are
- * passed in as arguments, and the exact location remains fixed. However, a select few Excel
- * functions have the ability to access cells that were not part of any reference passed as an
- * argument.<br/>
- * Two important functions with this feature are <b>INDIRECT</b> and <b>OFFSET</b><p/>
- *
- * In POI, the <tt>HSSFFormulaEvaluator</tt> 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 <tt>evaluate()</tt> method on the common
- * interface <tt>Function</tt> does not take a workbook parameter.<p>
- *
- * 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 <code>null</code>,
- * 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 <code>null</code>. Possibly an instance of <tt>ErrorEval</tt> 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);
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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);
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.<p/>
- *
- * HLOOKUP finds a column in a lookup table by the first row value and returns the value from another row.
- *
- * <b>Syntax</b>:<br/>
- * <b>HLOOKUP</b>(<b>lookup_value</b>, <b>table_array</b>, <b>row_index_num</b>, range_lookup)<p/>
- *
- * <b>lookup_value</b> The value to be found in the first column of the table array.<br/>
- * <b>table_array</> An area reference for the lookup data. <br/>
- * <b>row_index_num</b> a 1 based index specifying which row value of the lookup data will be returned.<br/>
- * <b>range_lookup</b> If TRUE (default), HLOOKUP finds the largest value less than or equal to
- * the lookup_value. If FALSE, only exact matches will be considered<br/>
- *
- * @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 <tt>AreaEval</tt>
- *
- * @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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR 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;
- }
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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<p/>
- *
- * Syntax : <br/>
- * INDEX ( reference, row_num[, column_num [, area_num]])</br>
- * INDEX ( array, row_num[, column_num])
- * <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions">
- * <tr><th>reference</th><td>typically an area reference, possibly a union of areas</td></tr>
- * <tr><th>array</th><td>a literal array value (currently not supported)</td></tr>
- * <tr><th>row_num</th><td>selects the row within the array or area reference</td></tr>
- * <tr><th>column_num</th><td>selects column within the array or area reference. default is 1</td></tr>
- * <tr><th>area_num</th><td>used when reference is a union of areas</td></tr>
- * </table>
- * <p/>
- *
- * @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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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<p/>
- *
- * INDIRECT() returns the cell or area reference denoted by the text argument.<p/>
- *
- * <b>Syntax</b>:</br>
- * <b>INDIRECT</b>(<b>ref_text</b>,isA1Style)<p/>
- *
- * <b>ref_text</b> a string representation of the desired reference as it would normally be written
- * in a cell formula.<br/>
- * <b>isA1Style</b> (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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.<p/>
- *
- * LOOKUP finds an index row in a lookup table by the first column value and returns the value from another column.
- *
- * <b>Syntax</b>:<br/>
- * <b>VLOOKUP</b>(<b>lookup_value</b>, <b>lookup_vector</b>, result_vector)<p/>
- *
- * <b>lookup_value</b> The value to be found in the lookup vector.<br/>
- * <b>lookup_vector</> An area reference for the lookup data. <br/>
- * <b>result_vector</b> Single row or single column area reference from which the result value is chosen.<br/>
- *
- * @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());
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <tt>AreaEval</tt>.
- */
- public interface ValueVector {
- ValueEval getItem(int index);
- int getSize();
- }
- /**
- * Enumeration to support <b>4</b> valued comparison results.<p/>
- * 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.<p/>
- *
- * A simple int might have done the same job, but there is risk in confusion with the well
- * known <tt>Comparable.compareTo()</tt> and <tt>Comparator.compare()</tt> 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 <tt>CompareResult</tt>: <tt>LESS_THAN</tt>, <tt>EQUAL</tt>,
- * <tt>GREATER_THAN</tt> or <tt>TYPE_MISMATCH</tt>
- */
- 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 (<b>col_index_num</b>
- * or <b>row_index_num</b> respectively).<br>
- * Sample behaviour:
- * <table border="0" cellpadding="1" cellspacing="2" summary="Sample behaviour">
- * <tr><th>Input Return</th><th>Value </th><th>Thrown Error</th></tr>
- * <tr><td>5</td><td>4</td><td> </td></tr>
- * <tr><td>2.9</td><td>2</td><td> </td></tr>
- * <tr><td>"5"</td><td>4</td><td> </td></tr>
- * <tr><td>"2.18e1"</td><td>21</td><td> </td></tr>
- * <tr><td>"-$2"</td><td>-3</td><td>*</td></tr>
- * <tr><td>FALSE</td><td>-1</td><td>*</td></tr>
- * <tr><td>TRUE</td><td>0</td><td> </td></tr>
- * <tr><td>"TRUE"</td><td> </td><td>#REF!</td></tr>
- * <tr><td>"abc"</td><td> </td><td>#REF!</td></tr>
- * <tr><td>""</td><td> </td><td>#REF!</td></tr>
- * <tr><td><blank></td><td> </td><td>#VALUE!</td></tr>
- * </table><br/>
- *
- * * 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 (<b>range_lookup</b>) 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<vector[newMid]),
- // this execution path only moves highIx it down as far as newMid, not midIx,
- // which would be more efficient.
- bsi.narrowSearch(newMid, cr.isLessThan());
- return -1;
- }
- }
- /**
- * Once the binary search has found a single match, (V/H)LOOKUP steps one by one over subsequent
- * values to choose the last matching item.
- */
- private static int findLastIndexInRunOfEqualValues(LookupValueComparer lookupComparer, ValueVector vector,
- int firstFoundIndex, int maxIx) {
- for(int i=firstFoundIndex+1; i<maxIx; i++) {
- if(!lookupComparer.compareTo(vector.getItem(i)).isEqual()) {
- return i-1;
- }
- }
- return maxIx - 1;
- }
-
- public static LookupValueComparer createLookupComparer(ValueEval lookupValue) throws EvaluationException {
-
- if (lookupValue instanceof BlankEval) {
- // blank eval can never be found in a lookup array
- throw new EvaluationException(ErrorEval.NA);
- }
- if (lookupValue instanceof StringEval) {
- return new StringLookupComparer((StringEval) lookupValue);
- }
- if (lookupValue instanceof NumberEval) {
- return new NumberLookupComparer((NumberEval) lookupValue);
- }
- if (lookupValue instanceof BoolEval) {
- return new BooleanLookupComparer((BoolEval) lookupValue);
- }
- throw new IllegalArgumentException("Bad lookup value type (" + lookupValue.getClass().getName() + ")");
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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 Lower 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.toLowerCase());
- }
-
- return retval;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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.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;
-import org.apache.poi.hssf.record.formula.functions.LookupUtils.CompareResult;
-import org.apache.poi.hssf.record.formula.functions.LookupUtils.LookupValueComparer;
-
-/**
- * Implementation for the MATCH() Excel function.<p/>
- *
- * <b>Syntax:</b><br/>
- * <b>MATCH</b>(<b>lookup_value</b>, <b>lookup_array</b>, match_type)<p/>
- *
- * Returns a 1-based index specifying at what position in the <b>lookup_array</b> the specified
- * <b>lookup_value</b> is found.<p/>
- *
- * Specific matching behaviour can be modified with the optional <b>match_type</b> parameter.
- *
- * <table border="0" cellpadding="1" cellspacing="0" summary="match_type parameter description">
- * <tr><th>Value</th><th>Matching Behaviour</th></tr>
- * <tr><td>1</td><td>(default) find the largest value that is less than or equal to lookup_value.
- * The lookup_array must be in ascending <i>order</i>*.</td></tr>
- * <tr><td>0</td><td>find the first value that is exactly equal to lookup_value.
- * The lookup_array can be in any order.</td></tr>
- * <tr><td>-1</td><td>find the smallest value that is greater than or equal to lookup_value.
- * The lookup_array must be in descending <i>order</i>*.</td></tr>
- * </table>
- *
- * * Note regarding <i>order</i> - For the <b>match_type</b> 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.<br>
- * The (ascending) sort order expected by MATCH() is:<br/>
- * numbers (low to high), strings (A to Z), boolean (FALSE to TRUE)<br/>
- * 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<lookupRange.length; i++) {
- CompareResult cmp = lookupComparer.compareTo(lookupRange[i]);
- if(cmp.isEqual()) {
- return i;
- }
- if(cmp.isGreaterThan()) {
- if(i<1) {
- throw new EvaluationException(ErrorEval.NA);
- }
- return i-1;
- }
- }
-
- throw new EvaluationException(ErrorEval.NA);
- }
-
- private static LookupValueComparer createLookupComparer(ValueEval lookupValue, boolean matchExact) throws EvaluationException {
- if (matchExact && lookupValue instanceof StringEval) {
- String stringValue = ((StringEval) lookupValue).getStringValue();
- if(isLookupValueWild(stringValue)) {
- throw new RuntimeException("Wildcard lookup values '" + stringValue + "' not supported yet");
- }
-
- }
- return LookupUtils.createLookupComparer(lookupValue);
- }
-
- private static boolean isLookupValueWild(String stringValue) {
- if(stringValue.indexOf('?') >=0 || stringValue.indexOf('*') >=0) {
- return true;
- }
- return false;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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.
- * <p>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.
- * <p>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.
- * <p>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.
- * <p>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.
- * <p>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.
- * <p>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
- * <br/>
- * If d > 0, returns short 1
- * <br/>
- * If d == 0, returns short 0
- * <p> 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<iSize; i++) {
- sum += values[i];
- }
- ave = sum / values.length;
- return ave;
- }
-
-
- /**
- * sum of all values
- * @param values
- */
- public static double sum(double[] values) {
- double sum = 0;
- for (int i=0, iSize=values.length; i<iSize; i++) {
- sum += values[i];
- }
- return sum;
- }
-
- /**
- * sum of squares of all values
- * @param values
- */
- public static double sumsq(double[] values) {
- double sumsq = 0;
- for (int i=0, iSize=values.length; i<iSize; i++) {
- sumsq += values[i]*values[i];
- }
- return sumsq;
- }
-
-
- /**
- * product of all values
- * @param values
- */
- public static double product(double[] values) {
- double product = 0;
- if (values!=null && values.length > 0) {
- product = 1;
- for (int i=0, iSize=values.length; i<iSize; i++) {
- product *= values[i];
- }
- }
- return product;
- }
-
- /**
- * min of all values. If supplied array is zero length,
- * Double.POSITIVE_INFINITY is returned.
- * @param values
- */
- public static double min(double[] values) {
- double min = Double.POSITIVE_INFINITY;
- for (int i=0, iSize=values.length; i<iSize; i++) {
- min = Math.min(min, values[i]);
- }
- return min;
- }
-
- /**
- * min of all values. If supplied array is zero length,
- * Double.NEGATIVE_INFINITY is returned.
- * @param values
- */
- public static double max(double[] values) {
- double max = Double.NEGATIVE_INFINITY;
- for (int i=0, iSize=values.length; i<iSize; i++) {
- max = Math.max(max, values[i]);
- }
- return max;
- }
-
- /**
- * Note: this function is different from java.lang.Math.floor(..).
- * <p>
- * When n and s are "valid" arguments, the returned value is: Math.floor(n/s) * s;
- * <br/>
- * n and s are invalid if any of following conditions are true:
- * <ul>
- * <li>s is zero</li>
- * <li>n is negative and s is positive</li>
- * <li>n is positive and s is negative</li>
- * </ul>
- * 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(..).
- * <p>
- * When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s;
- * <br/>
- * n and s are invalid if any of following conditions are true:
- * <ul>
- * <li>s is zero</li>
- * <li>n is negative and s is positive</li>
- * <li>n is positive and s is negative</li>
- * </ul>
- * 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;
- }
-
- /**
- * <br/> for all n >= 1; factorial n = n * (n-1) * (n-2) * ... * 1
- * <br/> else if n == 0; factorial n = 1
- * <br/> else if n < 0; factorial n = Double.NaN
- * <br/> 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.
- * <br/> The result has the sign of the divisor.
- * <br/> Examples:
- * <ul>
- * <li>mod(3.4, 2) = 1.4</li>
- * <li>mod(-3.4, 2) = 0.6</li>
- * <li>mod(-3.4, -2) = -1.4</li>
- * <li>mod(3.4, -2) = -0.6</li>
- * </ul>
- * 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<arrlen; j++) {
- double t = 1;
- for (int i=0; i<narr; i++) {
- t *= arrays[i][j];
- }
- d += t;
- }
- }
- catch (ArrayIndexOutOfBoundsException ae) {
- d = Double.NaN;
- }
-
- return d;
- }
-
- /**
- * returns the sum of difference of squares of corresponding double
- * value in each subarray: ie. sigma (xarr[i]^2-yarr[i]^2)
- * <br/>
- * 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<iSize; i++) {
- d += (xarr[i] + yarr[i]) * (xarr[i] - yarr[i]);
- }
- }
- catch (ArrayIndexOutOfBoundsException ae) {
- d = Double.NaN;
- }
-
- return d;
- }
-
- /**
- * returns the sum of sum of squares of corresponding double
- * value in each subarray: ie. sigma (xarr[i]^2 + yarr[i]^2)
- * <br/>
- * 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<iSize; i++) {
- d += (xarr[i] * xarr[i]) + (yarr[i] * yarr[i]);
- }
- }
- catch (ArrayIndexOutOfBoundsException ae) {
- d = Double.NaN;
- }
-
- return d;
- }
-
-
- /**
- * returns the sum of squares of difference of corresponding double
- * value in each subarray: ie. sigma ( (xarr[i]-yarr[i])^2 )
- * <br/>
- * 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<iSize; i++) {
- double t = (xarr[i] - yarr[i]);
- d += t * t;
- }
- }
- catch (ArrayIndexOutOfBoundsException ae) {
- d = Double.NaN;
- }
-
- return d;
- }
-
- /**
- * returns the total number of combinations possible when
- * k items are chosen out of total of n items. If the number
- * is too large, loss of precision may occur (since returned
- * value is double). If the returned value is larger than
- * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned.
- * If either of the parameters is negative, Double.NaN is returned.
- * @param n
- * @param k
- */
- public static double nChooseK(int n, int k) {
- double d = 1;
- if (n<0 || k<0 || n<k) {
- d= Double.NaN;
- }
- else {
- int minnk = Math.min(n-k, k);
- int maxnk = Math.max(n-k, k);
- for (int i=maxnk; i<n; i++) {
- d *= i+1;
- }
- d /= factorial(minnk);
- }
-
- return d;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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 Max 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.max(values) : 0;
- retval = (Double.isNaN(d) || Double.isInfinite(d))
- ? (ValueEval) ErrorEval.NUM_ERROR
- : new NumberEval(d);
- }
-
- return retval;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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<br/> MID returns a specific number of
- * characters from a text string, starting at the specified position.<p/>
- *
- * <b>Syntax<b>:<br/> <b>MID</b>(<b>text</b>, <b>start_num</b>,
- * <b>num_chars</b>)<br/>
- *
- * @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
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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 <code>null</code>.
- *
- * @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; i<iSize; i++) {
- double[] temp = getNumberArray(operands[i], srcRow, srcCol);
- if (temp == null) {
- return null; // error occurred.
- }
- retval.add(temp);
- }
- return retval.toArray();
- }
-
- /**
- * Same as getNumberArray(Eval[], int, short) except that this
- * takes Eval instead of Eval[].
- * @param operand
- * @param srcRow
- * @param srcCol
- */
- protected double[] getNumberArray(Eval operand, int srcRow, short srcCol) {
-
- if (operand instanceof AreaEval) {
- AreaEval ae = (AreaEval) operand;
- ValueEval[] values = ae.getValues();
- DoubleList retval = new DoubleList();
- for (int j=0, jSize=values.length; j<jSize; j++) {
- /*
- * TODO: For an AreaEval, we are constructing a RefEval
- * per element.
- * For now this is a tempfix solution since this may
- * require a more generic fix at the level of
- * HSSFFormulaEvaluator where we store an array
- * of RefEvals as the "values" array.
- */
- RefEval re = new Ref2DEval(null, values[j]);
- ValueEval ve = singleOperandEvaluate(re, srcRow, srcCol);
-
- if (ve instanceof NumericValueEval) {
- NumericValueEval nve = (NumericValueEval) ve;
- retval.add(nve.getNumberValue());
- }
- else if (ve instanceof BlankEval) {
- // note - blanks are ignored, so returned array will be smaller.
- }
- else {
- return null; // indicate to calling subclass that error occurred
- }
- }
- return retval.toArray();
- }
-
- // for ValueEvals other than AreaEval
- ValueEval ve = singleOperandEvaluate(operand, srcRow, srcCol);
-
- if (ve instanceof NumericValueEval) {
- NumericValueEval nve = (NumericValueEval) ve;
- return new double[] { nve.getNumberValue(), };
- }
-
- if (ve instanceof BlankEval) {
- // ignore blanks
- return EMPTY_DOUBLE_ARRAY;
- }
- return null;
- }
-
- /**
- * Ensures that a two dimensional array has all sub-arrays present and the same length
- * @return <code>false</code> 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<outerMax; i++) { // note - 'i=1' start at second sub-array
- double[] subArr = values[i];
- if (subArr == null) {
- return false;
- }
- if (innerMax != subArr.length) {
- return false;
- }
- }
- return true;
- }
-
-
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class N extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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;
-
-/**
- * Implementation of Excel function NA()
- *
- * @author Josh Micich
- */
-public final class Na implements Function {
-
- public Eval evaluate(Eval[] args, int srcCellRow, short srcCellCol) {
- return ErrorEval.NA;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Names extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Negbinomdist extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Normdist extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Norminv extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Normsdist extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Normsinv extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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.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.RefEval;
-import org.apache.poi.hssf.record.formula.eval.StringEval;
-import org.apache.poi.hssf.record.formula.eval.ValueEval;
-
-
-/**
- * @author Amol S. Deshmukh < amol at apache dot org >
- * The NOT boolean function. Returns negation of specified value
- * (treated as a boolean). If the specified arg is a number,
- * then it is true <=> '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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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()<p/>
- *
- * OFFSET returns an area reference that is a specified number of rows and columns from a
- * reference cell or area.<p/>
- *
- * <b>Syntax</b>:<br/>
- * <b>OFFSET</b>(<b>reference</b>, <b>rows</b>, <b>cols</b>, height, width)<p/>
- * <b>reference</b> is the base reference.<br/>
- * <b>rows</b> is the number of rows up or down from the base reference.<br/>
- * <b>cols</b> is the number of columns left or right from the base reference.<br/>
- * <b>height</b> (default same height as base reference) is the row count for the returned area reference.<br/>
- * <b>width</b> (default same width as base reference) is the column count for the returned area reference.<br/>
- *
- * @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.<p/>
- *
- * 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. <p/>
- *
- * @param translationAmount may be zero negative or positive
- *
- * @return the equivalent <tt>LinearOffsetRange</tt> 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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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<iSize; i++) {
- if (operands[i] instanceof AreaEval) {
- AreaEval ae = (AreaEval) operands[i];
- ValueEval[] values = ae.getValues();
- for (int j=0, jSize=values.length; j<jSize; j++) {
- ValueEval tempVe = singleOperandEvaluate(values[j], srcRow, srcCol, true);
- if (tempVe instanceof BoolEval) {
- b = b || ((BoolEval) tempVe).getBooleanValue();
- atleastOneNonBlank = true;
- }
- else if (tempVe instanceof ErrorEval) {
- retval = tempVe;
- break outer;
- }
- }
- }
- else {
- ValueEval tempVe = singleOperandEvaluate(operands[i], srcRow, srcCol, false);
- if (tempVe instanceof BoolEval) {
- b = b || ((BoolEval) tempVe).getBooleanValue();
- atleastOneNonBlank = true;
- }
- else if (tempVe instanceof ErrorEval) {
- retval = tempVe;
- break outer;
- }
- }
- }
-
- if (!atleastOneNonBlank) {
- retval = ErrorEval.VALUE_INVALID;
- }
-
- if (retval == null) { // if no error
- retval = b ? BoolEval.TRUE : BoolEval.FALSE;
- }
-
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Pearson extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Percentile extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Percentrank extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/*
- * Created on May 15, 2005
- *
- */
-package org.apache.poi.hssf.record.formula.functions;
-
-public class Permut extends NotImplementedFunction {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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 Pi implements Function {
-
- private static final NumberEval PI_EVAL = new NumberEval(Math.PI);
-
- public Eval evaluate(Eval[] operands, int srcRow, short srcCol) {
- ValueEval retval;
- switch (operands.length) {
- default:
- retval = ErrorEval.VALUE_INVALID;
- break;
- case 0:
- retval = PI_EVAL;
- }
- return retval;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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.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.ValueEval;
-
-/**
- * Implementation for the PMT() Excel function.<p/>
- *
- * <b>Syntax:</b><br/>
- * <b>PMT</b>(<b>rate</b>, <b>nper</b>, <b>pv</b>, fv, type)<p/>
- *
- * Returns the constant repayment amount required for a loan assuming a constant interest rate.<p/>
- *
- * <b>rate</b> the loan interest rate.<br/>
- * <b>nper</b> the number of loan repayments.<br/>
- * <b>pv</b> the present value of the future payments (or principle).<br/>
- * <b>fv</b> the future value (default zero) surplus cash at the end of the loan lifetime.<br/>
- * <b>type</b> whether payments are due at the beginning(1) or end(0 - default) of each payment period.<br/>
- *
- */
-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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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<iSize; i++) {
- s += v[i];
- }
- m = s / v.length;
- s = 0;
- for (int i=0, iSize=v.length; i<iSize; i++) {
- s += Math.abs(v[i]-m);
- }
- r = s / v.length;
- return r;
- }
-
- public static double stdev(double[] v) {
- double r = Double.NaN;
- if (v!=null && v.length > 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<iSize; i++) {
- for (int j=i+1, jSize=v.length; j<jSize; j++) {
- if (v[i] == v[j]) counts[i]++;
- }
- }
- double maxv = 0;
- int maxc = 0;
- for (int i=0, iSize=counts.length; i<iSize; i++) {
- if (counts[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<n; i++) {
- s += v[i];
- }
- m = s / n;
- s = 0;
- for (int i=0; i<n; i++) {
- s += (v[i]- m) * (v[i] - m);
- }
-
- r = (n == 1)
- ? 0
- : s;
- }
- return r;
- }
-
- /**
- * returns the kth largest element in the array. Duplicates
- * are considered as distinct values. Hence, eg.
- * for array {1,2,4,3,3} & k=2, returned value is 3.
- * <br/>
- * 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.
- * <br/>
- * 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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<p/>
- *
- * Syntax : <br/>
- * SUMPRODUCT ( array1[, array2[, array3[, ...]]])
- * <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions">
- * <tr><th>array1, ... arrayN </th><td>typically area references,
- * possibly cell references or scalar values</td></tr>
- * </table><br/>
- *
- * Let A<b>n</b><sub>(<b>i</b>,<b>j</b>)</sub> represent the element in the <b>i</b>th row <b>j</b>th column
- * of the <b>n</b>th array<br/>
- * Assuming each array has the same dimensions (W, H), the result is defined as:<br/>
- * SUMPRODUCT = Σ<sub><b>i</b>: 1..H</sub>
- * ( Σ<sub><b>j</b>: 1..W</sub>
- * ( Π<sub><b>n</b>: 1..N</sub>
- * A<b>n</b><sub>(<b>i</b>,<b>j</b>)</sub>
- * )
- * )
- *
- * @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; n<maxN; n++) {
- double val = getScalarValue(evalArgs[n]);
- term *= val;
- }
- return new NumberEval(term);
- }
-
- private double getScalarValue(Eval arg) throws EvalEx {
-
- Eval eval;
- if (arg instanceof RefEval) {
- RefEval re = (RefEval) arg;
- eval = re.getInnerValueEval();
- } else {
- eval = arg;
- }
-
- if (eval == null) {
- throw new RuntimeException("parameter may not be null");
- }
- if (eval instanceof AreaEval) {
- AreaEval ae = (AreaEval) eval;
- // an area ref can work as a scalar value if it is 1x1
- if(!ae.isColumn() || !ae.isRow()) {
- throw new EvalEx(ErrorEval.VALUE_INVALID);
- }
- eval = ae.getValues()[0];
- }
-
- if (!(eval instanceof ValueEval)) {
- throw new RuntimeException("Unexpected value eval class ("
- + eval.getClass().getName() + ")");
- }
-
- return getProductTerm((ValueEval) eval, true);
- }
-
- private Eval evaluateAreaSumProduct(Eval[] evalArgs) throws EvalEx {
- int maxN = evalArgs.length;
- AreaEval[] args = new AreaEval[maxN];
- try {
- System.arraycopy(evalArgs, 0, args, 0, maxN);
- } catch (ArrayStoreException e) {
- // one of the other args was not an AreaRef
- return ErrorEval.VALUE_INVALID;
- }
-
-
- AreaEval firstArg = args[0];
-
- int height = firstArg.getLastRow() - firstArg.getFirstRow() + 1;
- int width = firstArg.getLastColumn() - firstArg.getFirstColumn() + 1; // TODO - junit
-
-
-
- double[][][] elements = new double[maxN][][];
-
- for (int n = 0; n < maxN; n++) {
- elements[n] = evaluateArea(args[n], height, width);
- }
- double acc = 0;
-
- for(int r=0; r<height; r++) {
- for(int c=0; c<width; c++) {
- double term = 1D;
- for(int n=0; n<maxN; n++) {
- term *= elements[n][r][c];
- }
- acc += term;
- }
- }
-
- return new NumberEval(acc);
- }
-
- /**
- * @return a 2-D array of the specified height and width corresponding to the evaluated cell
- * values of the specified areaEval
- * @throws EvalEx if any ErrorEval value was encountered while evaluating the area
- */
- private static double[][] evaluateArea(AreaEval areaEval, int height, int width) throws EvalEx {
- int fr =areaEval.getFirstRow();
- int fc =areaEval.getFirstColumn();
-
- // check that height and width match
- if(areaEval.getLastRow() - fr + 1 != height) {
- throw new EvalEx(ErrorEval.VALUE_INVALID);
- }
- if(areaEval.getLastColumn() - fc + 1 != width) {
- throw new EvalEx(ErrorEval.VALUE_INVALID);
- }
- ValueEval[] values = areaEval.getValues();
- double[][] result = new double[height][width];
- for(int r=0; r<height; r++) {
- for(int c=0; c<width; c++) {
- ValueEval ve = values[r*width + c];
- result[r][c] = getProductTerm(ve, false);
- }
- }
- return result;
- }
-
- /**
- * Determines a <code>double</code> value for the specified <code>ValueEval</code>.
- * @param isScalarProduct <code>false</code> for SUMPRODUCTs over area refs.
- * @throws EvalEx if <code>ve</code> represents an error value.
- * <p/>
- * Note - string values and empty cells are interpreted differently depending on
- * <code>isScalarProduct</code>. 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() + ")");
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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()<p/>
- *
- * Calculates the sum of differences of squares in two arrays of the same size.<br/>
- * <b>Syntax</b>:<br/>
- * <b>SUMX2MY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
- *
- * result = Σ<sub>i: 0..n</sub>(x<sub>i</sub><sup>2</sup>-y<sub>i</sub><sup>2</sup>)
- *
- * @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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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()<p/>
- *
- * Calculates the sum of squares in two arrays of the same size.<br/>
- * <b>Syntax</b>:<br/>
- * <b>SUMX2PY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
- *
- * result = Σ<sub>i: 0..n</sub>(x<sub>i</sub><sup>2</sup>+y<sub>i</sub><sup>2</sup>)
- *
- * @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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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()<p/>
- *
- * Calculates the sum of squares of differences between two arrays of the same size.<br/>
- * <b>Syntax</b>:<br/>
- * <b>SUMXMY2</b>(<b>arrayX</b>, <b>arrayY</b>)<p/>
- *
- * result = Σ<sub>i: 0..n</sub>(x<sub>i</sub>-y<sub>i</sub>)<sup>2</sup>
- *
- * @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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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();
- }
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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;
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.<p/>
- *
- * VLOOKUP finds a row in a lookup table by the first column value and returns the value from another column.
- *
- * <b>Syntax</b>:<br/>
- * <b>VLOOKUP</b>(<b>lookup_value</b>, <b>table_array</b>, <b>col_index_num</b>, range_lookup)<p/>
- *
- * <b>lookup_value</b> The value to be found in the first column of the table array.<br/>
- * <b>table_array</> An area reference for the lookup data. <br/>
- * <b>col_index_num</b> a 1 based index specifying which column value of the lookup data will be returned.<br/>
- * <b>range_lookup</b> If TRUE (default), VLOOKUP finds the largest value less than or equal to
- * the lookup_value. If FALSE, only exact matches will be considered<br/>
- *
- * @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 <tt>AreaEval</tt>
- *
- * @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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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<iSize; i++) {
- Eval xEval = xops[i];
- Eval yEval = yops[i];
-
- if (isNumberEval(xEval) && isNumberEval(yEval)) {
- xResult[count] = getDoubleValue(xEval);
- yResult[count] = getDoubleValue(yEval);
- if (Double.isNaN(xResult[count]) || Double.isNaN(xResult[count])) {
- throw new EvaluationException(ErrorEval.NUM_ERROR);
- }
- count++;
- }
- }
-
- return new double[][] {
- trimToSize(xResult, count),
- trimToSize(yResult, count),
- };
- }
-
- private static double[][] getValues(Eval argX, Eval argY) throws EvaluationException {
-
- if (argX instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) argX);
- }
- if (argY instanceof ErrorEval) {
- throw new EvaluationException((ErrorEval) argY);
- }
-
- Eval[] xEvals;
- Eval[] yEvals;
- if (argX instanceof AreaEval) {
- AreaEval ae = (AreaEval) argX;
- xEvals = ae.getValues();
- } else {
- xEvals = new Eval[] { argX, };
- }
-
- if (argY instanceof AreaEval) {
- AreaEval ae = (AreaEval) argY;
- yEvals = ae.getValues();
- } else {
- yEvals = new Eval[] { argY, };
- }
-
- return getNumberArray(xEvals, yEvals);
- }
-
- private static double[] trimToSize(double[] arr, int len) {
- double[] tarr = arr;
- if (arr.length > 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;
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License 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
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the 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 {
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <tt>HSSFFormulaEvaluator.internalEvaluate()</tt>.
- * 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.<br/>
- */
- 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.<br/>
- *
- * In the case of a <code>true</code> return code, the caller should
- * continue evaluation of the specified cell, and also be sure to call
- * <tt>endEvaluate()</tt> when complete.<br/>
- *
- * In the case of a <code>false</code> return code, the caller should
- * return an evaluation result of
- * <tt>ErrorEval.CIRCULAR_REF_ERROR<tt>, and not call <tt>endEvaluate()</tt>.
- * <br/>
- * @return <code>true</code> if the specified cell has not been visited yet in the current
- * evaluation. <code>false</code> 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. <p/>
- *
- * Every successful call to <tt>startEvaluate</tt> must be followed by a
- * call to <tt>endEvaluate</tt> (recommended in a finally block) to enable
- * proper tracking of which cells are being evaluated at any point in time.<p/>
- *
- * 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <tt>EvaluationCycleDetector</tt> instance available to
- * each thread via a <tt>ThreadLocal</tt> in order to avoid adding a parameter
- * to a few protected methods within <tt>HSSFFormulaEvaluator</tt>.
- *
- * @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
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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.
- * <pre>
- * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
- * </pre>
- * 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:
- * <pre>
- * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
- * </pre>
- * 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<wb.getNumberOfSheets(); i++) {
- HSSFSheet sheet = wb.getSheetAt(i);
- 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);
- }
- }
- }
- }
-
-
- /**
- * Returns a CellValue wrapper around the supplied ValueEval instance.
- * @param eval
- */
- protected static CellValue getCellValueForEval(ValueEval eval) {
- CellValue retval = null;
- if (eval != null) {
- if (eval instanceof NumberEval) {
- NumberEval ne = (NumberEval) eval;
- retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC);
- retval.setNumberValue(ne.getNumberValue());
- }
- else if (eval instanceof BoolEval) {
- BoolEval be = (BoolEval) eval;
- retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN);
- retval.setBooleanValue(be.getBooleanValue());
- }
- else if (eval instanceof StringEval) {
- StringEval ne = (StringEval) eval;
- retval = new CellValue(HSSFCell.CELL_TYPE_STRING);
- retval.setStringValue(ne.getStringValue());
- }
- else if (eval instanceof BlankEval) {
- retval = new CellValue(HSSFCell.CELL_TYPE_BLANK);
- }
- else if (eval instanceof ErrorEval) {
- retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
- retval.setErrorValue((byte)((ErrorEval)eval).getErrorCode());
-// retval.setRichTextStringValue(new HSSFRichTextString("#An error occurred. check cell.getErrorCode()"));
- }
- else {
- retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
- }
- }
- return retval;
- }
-
- /**
- * Dev. Note: Internal evaluate must be passed only a formula cell
- * else a runtime exception will be thrown somewhere inside the method.
- * (Hence this is a private method.)
- */
- private static ValueEval internalEvaluate(HSSFCell srcCell, HSSFRow srcRow, HSSFSheet sheet, HSSFWorkbook workbook) {
- int srcRowNum = srcRow.getRowNum();
- short srcColNum = srcCell.getCellNum();
-
-
- EvaluationCycleDetector tracker = EvaluationCycleDetectorManager.getTracker();
-
- if(!tracker.startEvaluate(workbook, sheet, srcRowNum, srcColNum)) {
- return ErrorEval.CIRCULAR_REF_ERROR;
- }
- try {
- return evaluateCell(workbook, sheet, srcRowNum, srcColNum, srcCell.getCellFormula());
- } finally {
- tracker.endEvaluate(workbook, sheet, srcRowNum, srcColNum);
- }
- }
- private static ValueEval evaluateCell(HSSFWorkbook workbook, HSSFSheet sheet,
- int srcRowNum, short srcColNum, String cellFormulaText) {
- FormulaParser parser = new FormulaParser(cellFormulaText, workbook.getWorkbook());
- parser.parse();
- Ptg[] ptgs = parser.getRPNPtg();
- // -- parsing over --
-
-
- Stack stack = new Stack();
- for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
-
- // since we don't know how to handle these yet :(
- Ptg ptg = ptgs[i];
- if (ptg instanceof ControlPtg) { continue; }
- if (ptg instanceof MemErrPtg) { continue; }
- if (ptg instanceof MissingArgPtg) { continue; }
- if (ptg instanceof NamePtg) {
- // named ranges, macro functions
- NamePtg namePtg = (NamePtg) ptg;
- stack.push(new NameEval(namePtg.getIndex()));
- continue;
- }
- if (ptg instanceof NameXPtg) {
- // TODO - external functions
- continue;
- }
- if (ptg instanceof UnknownPtg) { continue; }
-
- if (ptg instanceof OperationPtg) {
- OperationPtg optg = (OperationPtg) ptg;
-
- // parens can be ignored since we have RPN tokens
- if (optg instanceof ParenthesisPtg) { continue; }
- if (optg instanceof AttrPtg) { continue; }
- if (optg instanceof UnionPtg) { continue; }
-
- OperationEval operation = OperationEvaluatorFactory.create(optg);
-
- int numops = operation.getNumberOfOperands();
- Eval[] ops = new Eval[numops];
-
- // storing the ops in reverse order since they are popping
- for (int j = numops - 1; j >= 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 <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
- * <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
- */
- 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 <br/>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("<ptg-group>");
- for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
- System.out.println("<ptg>");
- System.out.println(ptgs[i]);
- if (ptgs[i] instanceof OperationPtg) {
- System.out.println("numoperands: " + ((OperationPtg) ptgs[i]).getNumberOfOperands());
- }
- System.out.println("</ptg>");
- }
- System.out.println("</ptg-group>");
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <tt>OperationEval</tt> instances to help evaluate <tt>OperationPtg</tt>
- * 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;
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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<r.length; i++) {
- if(r[i] instanceof RowRecord) {
- RowRecord rr = (RowRecord)r[i];
- if(rr.getRowNumber() == 0) { row0 = i; }
- }
- }
- assertTrue(row0 > -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<r.length; i++) {
- if(r[i] instanceof LabelSSTRecord) {
- LabelSSTRecord lr = (LabelSSTRecord)r[i];
- if(lr.getRow() == 0 && lr.getColumn() == 0) { cell00 = i; }
- }
- }
- assertTrue(cell00 > -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<r.length; i++) {
- if(r[i] instanceof LastCellOfRowDummyRecord) {
- lrs[lrscount] = (LastCellOfRowDummyRecord)r[i];
- lrscount++;
- }
- }
-
- assertEquals(0, lrs[0].getLastColumnNumber());
- assertEquals(0, lrs[0].getRow());
-
- assertEquals(3, lrs[1].getLastColumnNumber());
- assertEquals(1, lrs[1].getRow());
-
- assertEquals(5, lrs[2].getLastColumnNumber());
- assertEquals(2, lrs[2].getRow());
-
- for(int i=3; i<=19; i++) {
- assertEquals(-1, lrs[i].getLastColumnNumber());
- assertEquals(i, lrs[i].getRow());
- }
-
- assertEquals(4, lrs[20].getLastColumnNumber());
- assertEquals(20, lrs[20].getRow());
-
- assertEquals(6, lrs[21].getLastColumnNumber());
- assertEquals(21, lrs[21].getRow());
-
- assertEquals(11, lrs[22].getLastColumnNumber());
- assertEquals(22, lrs[22].getRow());
- }
-
-
- public void testMissingCellRecords() throws Exception {
-
- // Find the cell at 0,0
- int cell00 = -1;
- for(int i=0; i<r.length; i++) {
- if(r[i] instanceof LabelSSTRecord) {
- LabelSSTRecord lr = (LabelSSTRecord)r[i];
- if(lr.getRow() == 0 && lr.getColumn() == 0) { cell00 = i; }
- }
- }
- assertTrue(cell00 > -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;
- }
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <tt>org.apache.poi.hssf.record.formula.eval</tt>.
- *
- * @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;
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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());
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.<p/> 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 <tt>InputStream</tt> 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.<p/> This test was
- * added <em>long</em> 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<p/>
- *
- * 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 <p/>
- */
- 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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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.<p/>
- * This class does not test implementors of <tt>Function</tt> and <tt>OperationEval</tt> in
- * isolation. Much of the evaluation engine (i.e. <tt>HSSFFormulaEvaluator</tt>, ...) gets
- * exercised as well. Tests for bug fixes and specific/tricky behaviour can be found in the
- * corresponding test class (<tt>TestXxxx</tt>) of the target (<tt>Xxxx</tt>) 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 = "<END-OF-FUNCTIONS>";
-
- /**
- * 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 <code>null</code> 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<stes.length) {
- if(!stes[startIx].getClassName().equals(Assert.class.getName())) {
- break;
- }
- startIx++;
- }
- // skip bottom frames (part of junit framework)
- int endIx = startIx+1;
- while(endIx < stes.length) {
- if(stes[endIx].getClassName().equals(TestCase.class.getName())) {
- break;
- }
- endIx++;
- }
- if(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; i<endIx; i++) {
- ps.println("\tat " + stes[i].toString());
- }
-
- }
-
- /**
- * @return <code>null</code> 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) + ")");
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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)<br/>
- * 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);
- }
-
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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);
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <code>Function</code>.
- *
- * @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;
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <code>Eval</code> 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)
- * <p/>
- * 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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.
- * <p/>
- * Assumes that the cell coordinate parameters of
- * <code>Function.evaluate(args, srcCellRow, srcCellCol)</code>
- * are not required.
- * <p/>
- * 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.
- * <p/>
- * 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();
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
-
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/*
- * 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;
-}
-
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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());
-
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT 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.<p/>
- * 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
- * (<tt>TestXxxx</tt>) of the target (<tt>Xxxx</tt>) 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 = "<end>";
- /** Used to indicate that the test on the current row should be ignored */
- public static final String SKIP_CURRENT_TEST_CASE_MARKER = "<skip>";
-
- }
-
- // 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 "<blank>";
- 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 "<blank>";
- 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<maxRows; rowIndex++) {
- HSSFRow r = sheet.getRow(rowIndex);
- String newMarkerValue = getMarkerColumnValue(r);
- if(r == null) {
- continue;
- }
- if(SS.TEST_CASES_END_MARKER.equalsIgnoreCase(newMarkerValue)) {
- // normal exit point
- return result;
- }
- if(SS.SKIP_CURRENT_TEST_CASE_MARKER.equalsIgnoreCase(newMarkerValue)) {
- // currently disabled test case row
- continue;
- }
- if(newMarkerValue != null) {
- currentGroupComment = newMarkerValue;
- }
- HSSFCell c = r.getCell(SS.COLUMN_INDEX_EVALUATION);
- if (c == null || c.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
- continue;
- }
- evaluator.setCurrentRow(r);
- CellValue actualValue = evaluator.evaluate(c);
- HSSFCell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_RESULT);
- String rowComment = getRowCommentColumnValue(r);
-
- String msgPrefix = formatTestCaseDetails(sheetName, r.getRowNum(), c, currentGroupComment, rowComment);
- try {
- confirmExpectedResult(msgPrefix, expectedValueCell, actualValue);
- _evaluationSuccessCount ++;
- if(result != Result.SOME_EVALUATIONS_FAILED) {
- result = Result.ALL_EVALUATIONS_SUCCEEDED;
- }
- } catch (RuntimeException e) {
- _evaluationFailureCount ++;
- printShortStackTrace(System.err, e);
- result = Result.SOME_EVALUATIONS_FAILED;
- } catch (AssertionFailedError e) {
- _evaluationFailureCount ++;
- printShortStackTrace(System.err, e);
- result = Result.SOME_EVALUATIONS_FAILED;
- }
-
- }
- throw new RuntimeException("Missing end marker '" + SS.TEST_CASES_END_MARKER
- + "' on sheet '" + sheetName + "'");
-
- }
-
-
- private static String formatTestCaseDetails(String sheetName, int rowNum, HSSFCell c, String currentGroupComment,
- String rowComment) {
-
- StringBuffer sb = new StringBuffer();
- CellReference cr = new CellReference(sheetName, rowNum, c.getCellNum(), false, false);
- sb.append(cr.formatAsString());
- sb.append(" {=").append(c.getCellFormula()).append("}");
-
- if(currentGroupComment != null) {
- sb.append(" '");
- sb.append(currentGroupComment);
- if(rowComment != null) {
- sb.append(" - ");
- sb.append(rowComment);
- }
- sb.append("' ");
- } else {
- if(rowComment != null) {
- sb.append(" '");
- sb.append(rowComment);
- sb.append("' ");
- }
- }
-
- return sb.toString();
- }
-
- /**
- * Asserts that the 'read me' comment page exists, and has this class' name in one of the
- * cells. This back-link is to make it easy to find this class if a reader encounters the
- * spreadsheet first.
- */
- private void confirmReadMeSheet(HSSFWorkbook workbook) {
- String firstSheetName = workbook.getSheetName(0);
- if(!firstSheetName.equalsIgnoreCase(SS.README_SHEET_NAME)) {
- throw new RuntimeException("First sheet's name was '" + firstSheetName + "' but expected '" + SS.README_SHEET_NAME + "'");
- }
- HSSFSheet sheet = workbook.getSheetAt(0);
- String specifiedClassName = sheet.getRow(2).getCell((short)0).getRichStringCellValue().getString();
- assertEquals("Test class name in spreadsheet comment", getClass().getName(), specifiedClassName);
-
- }
-
-
- /**
- * Useful to keep output concise when expecting many failures to be reported by this test case
- */
- private static void printShortStackTrace(PrintStream ps, Throwable e) {
- StackTraceElement[] stes = e.getStackTrace();
-
- int startIx = 0;
- // skip any top frames inside junit.framework.Assert
- while(startIx<stes.length) {
- if(!stes[startIx].getClassName().equals(Assert.class.getName())) {
- break;
- }
- startIx++;
- }
- // skip bottom frames (part of junit framework)
- int endIx = startIx+1;
- while(endIx < stes.length) {
- if(stes[endIx].getClassName().equals(TestCase.class.getName())) {
- break;
- }
- endIx++;
- }
- if(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; i<endIx; i++) {
- ps.println("\tat " + stes[i].toString());
- }
-
- }
-
- private static String getRowCommentColumnValue(HSSFRow r) {
- return getCellTextValue(r, SS.COLUMN_ROW_COMMENT, "row comment");
- }
-
- private static String getMarkerColumnValue(HSSFRow r) {
- return getCellTextValue(r, SS.COLUMN_INDEX_MARKER, "marker");
- }
-
- /**
- * @return <code>null</code> 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) + ")");
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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 <code>new Area2DEval(new AreaPtg(ref), values)</code>
- */
- 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 <tt>AreaEval</tt>.<br/>
- * 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;
- }
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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));
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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));
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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));
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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));
- }
-
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
-
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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<wb.getNumberOfSheets(); i++) {
- HSSFSheet s = wb.getSheetAt(i);
- HSSFFormulaEvaluator eval =
- new HSSFFormulaEvaluator(s, wb);
-
- Iterator it = s.rowIterator();
- while(it.hasNext()) {
- HSSFRow r = (HSSFRow)it.next();
- eval.setCurrentRow(r);
- process(r, eval);
- }
- }
- }
-
- protected void process(HSSFRow row, HSSFFormulaEvaluator eval) {
- Iterator it = row.cellIterator();
- while(it.hasNext()) {
- HSSFCell cell = (HSSFCell)it.next();
- if(cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
- continue;
- }
- FormulaRecordAggregate record = (FormulaRecordAggregate) cell.getCellValueRecord();
- FormulaRecord r = record.getFormulaRecord();
- List ptgs = r.getParsedExpression();
-
- String cellRef = new CellReference(row.getRowNum(), cell.getCellNum(), false, false).formatAsString();
- if(false && cellRef.equals("BP24")) { // TODO - replace System.out.println()s with asserts
- System.out.print(cellRef);
- System.out.println(" - has " + r.getNumberOfExpressionTokens()
- + " ptgs over " + r.getExpressionLength() + " tokens:");
- for(int i=0; i<ptgs.size(); i++) {
- String c = ptgs.get(i).getClass().toString();
- System.out.println("\t" + c.substring(c.lastIndexOf('.')+1) );
- }
- System.out.println("-> " + cell.getCellFormula());
- }
-
- CellValue evalResult = eval.evaluate(cell);
- assertNotNull(evalResult);
- }
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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);
- }
-}
+++ /dev/null
-package org.apache.poi.hssf.usermodel;\r
-/* ====================================================================\r
- Licensed to the Apache Software Foundation (ASF) under one or more\r
- contributor license agreements. See the NOTICE file distributed with\r
- this work for additional information regarding copyright ownership.\r
- The ASF licenses this file to You under the Apache License, Version 2.0\r
- (the "License"); you may not use this file except in compliance with\r
- the License. You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-==================================================================== */\r
-\r
-import junit.framework.TestCase;\r
-\r
-import java.io.IOException;\r
-import java.io.FileInputStream;\r
-import java.io.File;\r
-\r
-/**\r
- * Bug 44297: 32767+32768 is evaluated to -1\r
- * Fix: IntPtg must operate with unsigned short. Reading signed short results in incorrect formula calculation\r
- * if a formula has values in the interval [Short.MAX_VALUE, (Short.MAX_VALUE+1)*2]\r
- *\r
- * @author Yegor Kozlov\r
- */\r
-\r
-public class TestBug44297 extends TestCase {\r
- protected String cwd = System.getProperty("HSSF.testdata.path");\r
-\r
- public void test44297() throws IOException {\r
- FileInputStream in = new FileInputStream(new File(cwd, "44297.xls"));\r
- HSSFWorkbook wb = new HSSFWorkbook(in);\r
- in.close();\r
-\r
- HSSFRow row;\r
- HSSFCell cell;\r
-\r
- HSSFSheet sheet = wb.getSheetAt(0);\r
-\r
- HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb);\r
-\r
- row = (HSSFRow)sheet.getRow(0);\r
- cell = row.getCell((short)0);\r
- assertEquals("31+46", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(77, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(1);\r
- cell = row.getCell((short)0);\r
- assertEquals("30+53", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(83, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(2);\r
- cell = row.getCell((short)0);\r
- assertEquals("SUM(A1:A2)", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(160, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(4);\r
- cell = row.getCell((short)0);\r
- assertEquals("32767+32768", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(7);\r
- cell = row.getCell((short)0);\r
- assertEquals("32744+42333", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(8);\r
- cell = row.getCell((short)0);\r
- assertEquals("327680.0/32768", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(10, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(9);\r
- cell = row.getCell((short)0);\r
- assertEquals("32767+32769", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(10);\r
- cell = row.getCell((short)0);\r
- assertEquals("35000+36000", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0);\r
-\r
- row = (HSSFRow)sheet.getRow(11);\r
- cell = row.getCell((short)0);\r
- assertEquals("-1000000.0-3000000.0", cell.getCellFormula());\r
- eva.setCurrentRow(row);\r
- assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0);\r
- }\r
-\r
-}\r
+++ /dev/null
-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);
- }
-}
+++ /dev/null
-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());
- }
-}
+++ /dev/null
-/* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT 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());
- }
-}
+++ /dev/null
-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());
- }
-}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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<r.length; i++) {
+ if(r[i] instanceof RowRecord) {
+ RowRecord rr = (RowRecord)r[i];
+ if(rr.getRowNumber() == 0) { row0 = i; }
+ }
+ }
+ assertTrue(row0 > -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<r.length; i++) {
+ if(r[i] instanceof LabelSSTRecord) {
+ LabelSSTRecord lr = (LabelSSTRecord)r[i];
+ if(lr.getRow() == 0 && lr.getColumn() == 0) { cell00 = i; }
+ }
+ }
+ assertTrue(cell00 > -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<r.length; i++) {
+ if(r[i] instanceof LastCellOfRowDummyRecord) {
+ lrs[lrscount] = (LastCellOfRowDummyRecord)r[i];
+ lrscount++;
+ }
+ }
+
+ assertEquals(0, lrs[0].getLastColumnNumber());
+ assertEquals(0, lrs[0].getRow());
+
+ assertEquals(3, lrs[1].getLastColumnNumber());
+ assertEquals(1, lrs[1].getRow());
+
+ assertEquals(5, lrs[2].getLastColumnNumber());
+ assertEquals(2, lrs[2].getRow());
+
+ for(int i=3; i<=19; i++) {
+ assertEquals(-1, lrs[i].getLastColumnNumber());
+ assertEquals(i, lrs[i].getRow());
+ }
+
+ assertEquals(4, lrs[20].getLastColumnNumber());
+ assertEquals(20, lrs[20].getRow());
+
+ assertEquals(6, lrs[21].getLastColumnNumber());
+ assertEquals(21, lrs[21].getRow());
+
+ assertEquals(11, lrs[22].getLastColumnNumber());
+ assertEquals(22, lrs[22].getRow());
+ }
+
+
+ public void testMissingCellRecords() throws Exception {
+
+ // Find the cell at 0,0
+ int cell00 = -1;
+ for(int i=0; i<r.length; i++) {
+ if(r[i] instanceof LabelSSTRecord) {
+ LabelSSTRecord lr = (LabelSSTRecord)r[i];
+ if(lr.getRow() == 0 && lr.getColumn() == 0) { cell00 = i; }
+ }
+ }
+ assertTrue(cell00 > -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;
+ }
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <tt>org.apache.poi.hssf.record.formula.eval</tt>.
+ *
+ * @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;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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());
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.<p/> 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 <tt>InputStream</tt> 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.<p/> This test was
+ * added <em>long</em> 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<p/>
+ *
+ * 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 <p/>
+ */
+ 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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.<p/>
+ * This class does not test implementors of <tt>Function</tt> and <tt>OperationEval</tt> in
+ * isolation. Much of the evaluation engine (i.e. <tt>HSSFFormulaEvaluator</tt>, ...) gets
+ * exercised as well. Tests for bug fixes and specific/tricky behaviour can be found in the
+ * corresponding test class (<tt>TestXxxx</tt>) of the target (<tt>Xxxx</tt>) 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 = "<END-OF-FUNCTIONS>";
+
+ /**
+ * 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 <code>null</code> 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<stes.length) {
+ if(!stes[startIx].getClassName().equals(Assert.class.getName())) {
+ break;
+ }
+ startIx++;
+ }
+ // skip bottom frames (part of junit framework)
+ int endIx = startIx+1;
+ while(endIx < stes.length) {
+ if(stes[endIx].getClassName().equals(TestCase.class.getName())) {
+ break;
+ }
+ endIx++;
+ }
+ if(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; i<endIx; i++) {
+ ps.println("\tat " + stes[i].toString());
+ }
+
+ }
+
+ /**
+ * @return <code>null</code> 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) + ")");
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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)<br/>
+ * 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);
+ }
+
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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);
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <code>Function</code>.
+ *
+ * @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;
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <code>Eval</code> 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)
+ * <p/>
+ * 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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.
+ * <p/>
+ * Assumes that the cell coordinate parameters of
+ * <code>Function.evaluate(args, srcCellRow, srcCellCol)</code>
+ * are not required.
+ * <p/>
+ * 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.
+ * <p/>
+ * 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();
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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());
+
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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.<p/>
+ * 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
+ * (<tt>TestXxxx</tt>) of the target (<tt>Xxxx</tt>) 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 = "<end>";
+ /** Used to indicate that the test on the current row should be ignored */
+ public static final String SKIP_CURRENT_TEST_CASE_MARKER = "<skip>";
+
+ }
+
+ // 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 "<blank>";
+ 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 "<blank>";
+ 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<maxRows; rowIndex++) {
+ HSSFRow r = sheet.getRow(rowIndex);
+ String newMarkerValue = getMarkerColumnValue(r);
+ if(r == null) {
+ continue;
+ }
+ if(SS.TEST_CASES_END_MARKER.equalsIgnoreCase(newMarkerValue)) {
+ // normal exit point
+ return result;
+ }
+ if(SS.SKIP_CURRENT_TEST_CASE_MARKER.equalsIgnoreCase(newMarkerValue)) {
+ // currently disabled test case row
+ continue;
+ }
+ if(newMarkerValue != null) {
+ currentGroupComment = newMarkerValue;
+ }
+ HSSFCell c = r.getCell(SS.COLUMN_INDEX_EVALUATION);
+ if (c == null || c.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
+ continue;
+ }
+ evaluator.setCurrentRow(r);
+ CellValue actualValue = evaluator.evaluate(c);
+ HSSFCell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_RESULT);
+ String rowComment = getRowCommentColumnValue(r);
+
+ String msgPrefix = formatTestCaseDetails(sheetName, r.getRowNum(), c, currentGroupComment, rowComment);
+ try {
+ confirmExpectedResult(msgPrefix, expectedValueCell, actualValue);
+ _evaluationSuccessCount ++;
+ if(result != Result.SOME_EVALUATIONS_FAILED) {
+ result = Result.ALL_EVALUATIONS_SUCCEEDED;
+ }
+ } catch (RuntimeException e) {
+ _evaluationFailureCount ++;
+ printShortStackTrace(System.err, e);
+ result = Result.SOME_EVALUATIONS_FAILED;
+ } catch (AssertionFailedError e) {
+ _evaluationFailureCount ++;
+ printShortStackTrace(System.err, e);
+ result = Result.SOME_EVALUATIONS_FAILED;
+ }
+
+ }
+ throw new RuntimeException("Missing end marker '" + SS.TEST_CASES_END_MARKER
+ + "' on sheet '" + sheetName + "'");
+
+ }
+
+
+ private static String formatTestCaseDetails(String sheetName, int rowNum, HSSFCell c, String currentGroupComment,
+ String rowComment) {
+
+ StringBuffer sb = new StringBuffer();
+ CellReference cr = new CellReference(sheetName, rowNum, c.getCellNum(), false, false);
+ sb.append(cr.formatAsString());
+ sb.append(" {=").append(c.getCellFormula()).append("}");
+
+ if(currentGroupComment != null) {
+ sb.append(" '");
+ sb.append(currentGroupComment);
+ if(rowComment != null) {
+ sb.append(" - ");
+ sb.append(rowComment);
+ }
+ sb.append("' ");
+ } else {
+ if(rowComment != null) {
+ sb.append(" '");
+ sb.append(rowComment);
+ sb.append("' ");
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Asserts that the 'read me' comment page exists, and has this class' name in one of the
+ * cells. This back-link is to make it easy to find this class if a reader encounters the
+ * spreadsheet first.
+ */
+ private void confirmReadMeSheet(HSSFWorkbook workbook) {
+ String firstSheetName = workbook.getSheetName(0);
+ if(!firstSheetName.equalsIgnoreCase(SS.README_SHEET_NAME)) {
+ throw new RuntimeException("First sheet's name was '" + firstSheetName + "' but expected '" + SS.README_SHEET_NAME + "'");
+ }
+ HSSFSheet sheet = workbook.getSheetAt(0);
+ String specifiedClassName = sheet.getRow(2).getCell((short)0).getRichStringCellValue().getString();
+ assertEquals("Test class name in spreadsheet comment", getClass().getName(), specifiedClassName);
+
+ }
+
+
+ /**
+ * Useful to keep output concise when expecting many failures to be reported by this test case
+ */
+ private static void printShortStackTrace(PrintStream ps, Throwable e) {
+ StackTraceElement[] stes = e.getStackTrace();
+
+ int startIx = 0;
+ // skip any top frames inside junit.framework.Assert
+ while(startIx<stes.length) {
+ if(!stes[startIx].getClassName().equals(Assert.class.getName())) {
+ break;
+ }
+ startIx++;
+ }
+ // skip bottom frames (part of junit framework)
+ int endIx = startIx+1;
+ while(endIx < stes.length) {
+ if(stes[endIx].getClassName().equals(TestCase.class.getName())) {
+ break;
+ }
+ endIx++;
+ }
+ if(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; i<endIx; i++) {
+ ps.println("\tat " + stes[i].toString());
+ }
+
+ }
+
+ private static String getRowCommentColumnValue(HSSFRow r) {
+ return getCellTextValue(r, SS.COLUMN_ROW_COMMENT, "row comment");
+ }
+
+ private static String getMarkerColumnValue(HSSFRow r) {
+ return getCellTextValue(r, SS.COLUMN_INDEX_MARKER, "marker");
+ }
+
+ /**
+ * @return <code>null</code> 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) + ")");
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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 <code>new Area2DEval(new AreaPtg(ref), values)</code>
+ */
+ 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 <tt>AreaEval</tt>.<br/>
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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));
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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));
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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));
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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));
+ }
+
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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<wb.getNumberOfSheets(); i++) {
+ HSSFSheet s = wb.getSheetAt(i);
+ HSSFFormulaEvaluator eval =
+ new HSSFFormulaEvaluator(s, wb);
+
+ Iterator it = s.rowIterator();
+ while(it.hasNext()) {
+ HSSFRow r = (HSSFRow)it.next();
+ eval.setCurrentRow(r);
+ process(r, eval);
+ }
+ }
+ }
+
+ protected void process(HSSFRow row, HSSFFormulaEvaluator eval) {
+ Iterator it = row.cellIterator();
+ while(it.hasNext()) {
+ HSSFCell cell = (HSSFCell)it.next();
+ if(cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
+ continue;
+ }
+ FormulaRecordAggregate record = (FormulaRecordAggregate) cell.getCellValueRecord();
+ FormulaRecord r = record.getFormulaRecord();
+ List ptgs = r.getParsedExpression();
+
+ String cellRef = new CellReference(row.getRowNum(), cell.getCellNum(), false, false).formatAsString();
+ if(false && cellRef.equals("BP24")) { // TODO - replace System.out.println()s with asserts
+ System.out.print(cellRef);
+ System.out.println(" - has " + r.getNumberOfExpressionTokens()
+ + " ptgs over " + r.getExpressionLength() + " tokens:");
+ for(int i=0; i<ptgs.size(); i++) {
+ String c = ptgs.get(i).getClass().toString();
+ System.out.println("\t" + c.substring(c.lastIndexOf('.')+1) );
+ }
+ System.out.println("-> " + cell.getCellFormula());
+ }
+
+ CellValue evalResult = eval.evaluate(cell);
+ assertNotNull(evalResult);
+ }
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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);
+ }
+}
--- /dev/null
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT 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());
+ }
+}
--- /dev/null
+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());
+ }
+}