git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@642904 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ede1814a1d
commit
5b0efa8e57
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
<!-- Don't forget to update status.xml too! -->
|
<!-- Don't forget to update status.xml too! -->
|
||||||
<release version="3.0.3-beta1" date="2008-04-??">
|
<release version="3.0.3-beta1" date="2008-04-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="add">Various fixes: Recognising var-arg built-in functions #44675, ExternalNameRecord serialisation bug #44695, PMT() bug #44691</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
|
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action>
|
<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">Move the missing record aware eventusermodel code out of scratchpad</action>
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
<!-- Don't forget to update changes.xml too! -->
|
<!-- Don't forget to update changes.xml too! -->
|
||||||
<changes>
|
<changes>
|
||||||
<release version="3.0.3-beta1" date="2008-04-??">
|
<release version="3.0.3-beta1" date="2008-04-??">
|
||||||
|
<action dev="POI-DEVELOPERS" type="add">Various fixes: Recognising var-arg built-in functions #44675, ExternalNameRecord serialisation bug #44695, PMT() bug #44691</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
|
<action dev="POI-DEVELOPERS" type="add">30311 - More work on Conditional Formatting</action>
|
||||||
<action dev="POI-DEVELOPERS" type="add">Move the Formula Evaluator code out of scratchpad</action>
|
<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">Move the missing record aware eventusermodel code out of scratchpad</action>
|
||||||
|
@ -28,8 +28,6 @@ import org.apache.poi.hssf.record.formula.*;
|
|||||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
|
import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
|
||||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class parses a formula string into a List of tokens in RPN order.
|
* This class parses a formula string into a List of tokens in RPN order.
|
||||||
* Inspired by
|
* Inspired by
|
||||||
|
@ -37,7 +37,7 @@ public final class ExternalNameRecord extends Record {
|
|||||||
private static final int OPT_PICTURE_LINK = 0x0004;
|
private static final int OPT_PICTURE_LINK = 0x0004;
|
||||||
private static final int OPT_STD_DOCUMENT_NAME = 0x0008;
|
private static final int OPT_STD_DOCUMENT_NAME = 0x0008;
|
||||||
private static final int OPT_OLE_LINK = 0x0010;
|
private static final int OPT_OLE_LINK = 0x0010;
|
||||||
// private static final int OPT_CLIP_FORMAT_MASK = 0x7FE0;
|
// private static final int OPT_CLIP_FORMAT_MASK = 0x7FE0;
|
||||||
private static final int OPT_ICONIFIED_PICTURE_LINK= 0x8000;
|
private static final int OPT_ICONIFIED_PICTURE_LINK= 0x8000;
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
|
|
||||||
|
|
||||||
package org.apache.poi.hssf.record.formula;
|
package org.apache.poi.hssf.record.formula;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.hssf.record.RecordInputStream;
|
import org.apache.poi.hssf.record.RecordInputStream;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.formula.function;
|
package org.apache.poi.hssf.record.formula.function;
|
||||||
/**
|
/**
|
||||||
|
* Holds information about Excel built-in functions.
|
||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
@ -46,7 +47,7 @@ public final class FunctionMetadata {
|
|||||||
return _maxParams;
|
return _maxParams;
|
||||||
}
|
}
|
||||||
public boolean hasFixedArgsLength() {
|
public boolean hasFixedArgsLength() {
|
||||||
return _minParams == _maxParams;
|
return _minParams == _maxParams;
|
||||||
}
|
}
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer(64);
|
StringBuffer sb = new StringBuffer(64);
|
||||||
|
@ -46,7 +46,7 @@ final class FunctionMetadataReader {
|
|||||||
|
|
||||||
public static FunctionMetadataRegistry createRegistry() {
|
public static FunctionMetadataRegistry createRegistry() {
|
||||||
InputStream is = FunctionMetadataReader.class.getResourceAsStream(METADATA_FILE_NAME);
|
InputStream is = FunctionMetadataReader.class.getResourceAsStream(METADATA_FILE_NAME);
|
||||||
if(is == null) {
|
if (is == null) {
|
||||||
throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found");
|
throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,11 @@ package org.apache.poi.hssf.record.formula.function;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
/**
|
||||||
|
* Allows clients to get <tt>FunctionMetadata</tt> instances for any built-in function of Excel.
|
||||||
|
*
|
||||||
|
* @author Josh Micich
|
||||||
|
*/
|
||||||
public final class FunctionMetadataRegistry {
|
public final class FunctionMetadataRegistry {
|
||||||
/**
|
/**
|
||||||
* The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
|
* The name of the IF function (i.e. "IF"). Extracted as a constant for clarity.
|
||||||
@ -35,7 +39,6 @@ public final class FunctionMetadataRegistry {
|
|||||||
private static FunctionMetadataRegistry getInstance() {
|
private static FunctionMetadataRegistry getInstance() {
|
||||||
if (_instance == null) {
|
if (_instance == null) {
|
||||||
_instance = FunctionMetadataReader.createRegistry();
|
_instance = FunctionMetadataReader.createRegistry();
|
||||||
// _instance = POIFunctionMetadataCreator.createInstance();
|
|
||||||
}
|
}
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ public final class Pmt extends FinanceFunction {
|
|||||||
return ErrorEval.VALUE_INVALID;
|
return ErrorEval.VALUE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// evaluate first three (always present) args
|
// evaluate first three (always present) args
|
||||||
double rate = evalArg(args[0], srcRow, srcCol);
|
double rate = evalArg(args[0], srcRow, srcCol);
|
||||||
double nper = evalArg(args[1], srcRow, srcCol);
|
double nper = evalArg(args[1], srcRow, srcCol);
|
||||||
double pv = evalArg(args[2], srcRow, srcCol);
|
double pv = evalArg(args[2], srcRow, srcCol);
|
||||||
@ -67,10 +67,10 @@ public final class Pmt extends FinanceFunction {
|
|||||||
}
|
}
|
||||||
double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning);
|
double d = FinanceLib.pmt(rate, nper, pv, fv, arePaymentsAtPeriodBeginning);
|
||||||
if (Double.isNaN(d)) {
|
if (Double.isNaN(d)) {
|
||||||
return (ValueEval) ErrorEval.VALUE_INVALID;
|
return ErrorEval.VALUE_INVALID;
|
||||||
}
|
}
|
||||||
if (Double.isInfinite(d)) {
|
if (Double.isInfinite(d)) {
|
||||||
return (ValueEval) ErrorEval.NUM_ERROR;
|
return ErrorEval.NUM_ERROR;
|
||||||
}
|
}
|
||||||
return new NumberEval(d);
|
return new NumberEval(d);
|
||||||
} catch (EvaluationException e) {
|
} catch (EvaluationException e) {
|
||||||
|
@ -19,6 +19,7 @@ package org.apache.poi.hssf.record;
|
|||||||
|
|
||||||
import org.apache.poi.hssf.record.aggregates.AllRecordAggregateTests;
|
import org.apache.poi.hssf.record.aggregates.AllRecordAggregateTests;
|
||||||
import org.apache.poi.hssf.record.formula.AllFormulaTests;
|
import org.apache.poi.hssf.record.formula.AllFormulaTests;
|
||||||
|
import org.apache.poi.hssf.record.formula.functions.AllIndividualFunctionEvaluationTests;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
@ -17,13 +17,15 @@
|
|||||||
|
|
||||||
package org.apache.poi.hssf.record.formula;
|
package org.apache.poi.hssf.record.formula;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.formula.eval.AllFormulaEvalTests;
|
||||||
import org.apache.poi.hssf.record.formula.function.AllFormulaFunctionTests;
|
import org.apache.poi.hssf.record.formula.function.AllFormulaFunctionTests;
|
||||||
|
import org.apache.poi.hssf.record.formula.functions.AllIndividualFunctionEvaluationTests;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all tests for this package.
|
* Collects all tests for <tt>org.apache.poi.hssf.record.formula</tt>.
|
||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
@ -31,6 +33,10 @@ public class AllFormulaTests {
|
|||||||
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
TestSuite result = new TestSuite(AllFormulaTests.class.getName());
|
TestSuite result = new TestSuite(AllFormulaTests.class.getName());
|
||||||
|
result.addTest(AllFormulaEvalTests.suite());
|
||||||
|
result.addTest(AllFormulaFunctionTests.suite());
|
||||||
|
result.addTest(AllIndividualFunctionEvaluationTests.suite());
|
||||||
|
|
||||||
result.addTestSuite(TestArea3DPtg.class);
|
result.addTestSuite(TestArea3DPtg.class);
|
||||||
result.addTestSuite(TestAreaErrPtg.class);
|
result.addTestSuite(TestAreaErrPtg.class);
|
||||||
result.addTestSuite(TestAreaPtg.class);
|
result.addTestSuite(TestAreaPtg.class);
|
||||||
|
@ -21,7 +21,7 @@ import junit.framework.Test;
|
|||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all tests for this package.
|
* Collects all tests for this <tt>org.apache.poi.hssf.record.formula.function</tt>.
|
||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
|
@ -56,7 +56,7 @@ import org.xml.sax.helpers.XMLReaderFactory;
|
|||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public class ExcelFileFormatDocFunctionExtractor {
|
public final class ExcelFileFormatDocFunctionExtractor {
|
||||||
|
|
||||||
private static final String SOURCE_DOC_FILE_NAME = "excelfileformat.odt";
|
private static final String SOURCE_DOC_FILE_NAME = "excelfileformat.odt";
|
||||||
|
|
||||||
@ -407,30 +407,30 @@ public class ExcelFileFormatDocFunctionExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void outputLicenseHeader(PrintStream ps) {
|
private static void outputLicenseHeader(PrintStream ps) {
|
||||||
String[] lines= {
|
String[] lines= {
|
||||||
"Licensed to the Apache Software Foundation (ASF) under one or more",
|
"Licensed to the Apache Software Foundation (ASF) under one or more",
|
||||||
"contributor license agreements. See the NOTICE file distributed with",
|
"contributor license agreements. See the NOTICE file distributed with",
|
||||||
"this work for additional information regarding copyright ownership.",
|
"this work for additional information regarding copyright ownership.",
|
||||||
"The ASF licenses this file to You under the Apache License, Version 2.0",
|
"The ASF licenses this file to You under the Apache License, Version 2.0",
|
||||||
"(the \"License\"); you may not use this file except in compliance with",
|
"(the \"License\"); you may not use this file except in compliance with",
|
||||||
"the License. You may obtain a copy of the License at",
|
"the License. You may obtain a copy of the License at",
|
||||||
"",
|
"",
|
||||||
" http://www.apache.org/licenses/LICENSE-2.0",
|
" http://www.apache.org/licenses/LICENSE-2.0",
|
||||||
"",
|
"",
|
||||||
"Unless required by applicable law or agreed to in writing, software",
|
"Unless required by applicable law or agreed to in writing, software",
|
||||||
"distributed under the License is distributed on an \"AS IS\" BASIS,",
|
"distributed under the License is distributed on an \"AS IS\" BASIS,",
|
||||||
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
|
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
|
||||||
"See the License for the specific language governing permissions and",
|
"See the License for the specific language governing permissions and",
|
||||||
"limitations under the License.",
|
"limitations under the License.",
|
||||||
};
|
};
|
||||||
for (int i = 0; i < lines.length; i++) {
|
for (int i = 0; i < lines.length; i++) {
|
||||||
ps.print("# ");
|
ps.print("# ");
|
||||||
ps.println(lines[i]);
|
ps.println(lines[i]);
|
||||||
}
|
}
|
||||||
ps.println();
|
ps.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helps identify the source file
|
* Helps identify the source file
|
||||||
*/
|
*/
|
||||||
private static String getFileCRC(File f) {
|
private static String getFileCRC(File f) {
|
||||||
@ -453,8 +453,8 @@ public class ExcelFileFormatDocFunctionExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static File getSourceFile() {
|
private static File getSourceFile() {
|
||||||
if (true) {
|
if (false) {
|
||||||
File dir = new File("c:/josh/ref-docs");
|
File dir = new File("c:/temp");
|
||||||
File effDocFile = new File(dir, SOURCE_DOC_FILE_NAME);
|
File effDocFile = new File(dir, SOURCE_DOC_FILE_NAME);
|
||||||
return effDocFile;
|
return effDocFile;
|
||||||
}
|
}
|
||||||
@ -499,5 +499,4 @@ public class ExcelFileFormatDocFunctionExtractor {
|
|||||||
File outFile = new File("functionMetadata-asGenerated.txt");
|
File outFile = new File("functionMetadata-asGenerated.txt");
|
||||||
processFile(effDocFile, outFile);
|
processFile(effDocFile, outFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,26 +18,27 @@
|
|||||||
package org.apache.poi.hssf.record.formula.function;
|
package org.apache.poi.hssf.record.formula.function;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Josh Micich
|
* @author Josh Micich
|
||||||
*/
|
*/
|
||||||
public final class TestFunctionMetadataRegistry extends TestCase {
|
public final class TestFunctionMetadataRegistry extends TestCase {
|
||||||
|
|
||||||
public void testWellKnownFunctions() {
|
public void testWellKnownFunctions() {
|
||||||
confirmFunction(0, "COUNT");
|
confirmFunction(0, "COUNT");
|
||||||
confirmFunction(1, "IF");
|
confirmFunction(1, "IF");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void confirmFunction(int index, String funcName) {
|
private static void confirmFunction(int index, String funcName) {
|
||||||
FunctionMetadata fm;
|
FunctionMetadata fm;
|
||||||
fm = FunctionMetadataRegistry.getFunctionByIndex(index);
|
fm = FunctionMetadataRegistry.getFunctionByIndex(index);
|
||||||
assertNotNull(fm);
|
assertNotNull(fm);
|
||||||
assertEquals(funcName, fm.getName());
|
assertEquals(funcName, fm.getName());
|
||||||
|
|
||||||
fm = FunctionMetadataRegistry.getFunctionByName(funcName);
|
fm = FunctionMetadataRegistry.getFunctionByName(funcName);
|
||||||
assertNotNull(fm);
|
assertNotNull(fm);
|
||||||
assertEquals(index, fm.getIndex());
|
assertEquals(index, fm.getIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,8 @@ public final class TestParseMissingBuiltInFuncs extends TestCase {
|
|||||||
}
|
}
|
||||||
AbstractFunctionPtg func = (AbstractFunctionPtg) ptgF;
|
AbstractFunctionPtg func = (AbstractFunctionPtg) ptgF;
|
||||||
if(func.getFunctionIndex() == 255) {
|
if(func.getFunctionIndex() == 255) {
|
||||||
throw new AssertionFailedError("Failed to recognise built-in function in formula '"
|
throw new AssertionFailedError("Failed to recognise built-in function in formula '"
|
||||||
+ formula + "'");
|
+ formula + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(expPtgArraySize, ptgs.length);
|
assertEquals(expPtgArraySize, ptgs.length);
|
||||||
|
@ -56,9 +56,9 @@ public final class TestReadMissingBuiltInFuncs extends TestCase {
|
|||||||
formula = getCellFormula(0);
|
formula = getCellFormula(0);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
if(e.getMessage().startsWith("Too few arguments")) {
|
if(e.getMessage().startsWith("Too few arguments")) {
|
||||||
if(e.getMessage().indexOf("AttrPtg") > 0) {
|
if(e.getMessage().indexOf("AttrPtg") > 0) {
|
||||||
throw afe("tAttrVolatile not supported in FormulaParser.toFormulaString");
|
throw afe("tAttrVolatile not supported in FormulaParser.toFormulaString");
|
||||||
}
|
}
|
||||||
throw afe("NOW() registered with 1 arg instead of 0");
|
throw afe("NOW() registered with 1 arg instead of 0");
|
||||||
}
|
}
|
||||||
if(e.getMessage().startsWith("too much stuff")) {
|
if(e.getMessage().startsWith("too much stuff")) {
|
||||||
|
@ -27,9 +27,8 @@ import junit.framework.TestSuite;
|
|||||||
*/
|
*/
|
||||||
public final class AllIndividualFunctionEvaluationTests {
|
public final class AllIndividualFunctionEvaluationTests {
|
||||||
|
|
||||||
// TODO - have this suite incorporated into a higher level one
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
TestSuite result = new TestSuite("Tests for org.apache.poi.hssf.record.formula.functions");
|
TestSuite result = new TestSuite(AllIndividualFunctionEvaluationTests.class.getName());
|
||||||
result.addTestSuite(TestAverage.class);
|
result.addTestSuite(TestAverage.class);
|
||||||
result.addTestSuite(TestCountFuncs.class);
|
result.addTestSuite(TestCountFuncs.class);
|
||||||
result.addTestSuite(TestDate.class);
|
result.addTestSuite(TestDate.class);
|
||||||
|
Loading…
Reference in New Issue
Block a user