improved LinkTable to support registering external UDFs.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1039621 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6411c93217
commit
4c6b49e5ab
@ -83,6 +83,7 @@ import org.apache.poi.hssf.record.WriteProtectRecord;
|
|||||||
import org.apache.poi.hssf.record.common.UnicodeString;
|
import org.apache.poi.hssf.record.common.UnicodeString;
|
||||||
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
||||||
import org.apache.poi.ss.formula.FormulaShifter;
|
import org.apache.poi.ss.formula.FormulaShifter;
|
||||||
|
import org.apache.poi.ss.formula.udf.UDFFinder;
|
||||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||||
import org.apache.poi.hssf.util.HSSFColor;
|
import org.apache.poi.hssf.util.HSSFColor;
|
||||||
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
|
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
|
||||||
@ -2300,8 +2301,22 @@ public final class InternalWorkbook {
|
|||||||
return linkTable.resolveNameXText(refIndex, definedNameIndex);
|
return linkTable.resolveNameXText(refIndex, definedNameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NameXPtg getNameXPtg(String name) {
|
/**
|
||||||
return getOrCreateLinkTable().getNameXPtg(name);
|
*
|
||||||
|
* @param name the name of an external function, typically a name of a UDF
|
||||||
|
* @param udf locator of user-defiend functions to resolve names of VBA and Add-In functions
|
||||||
|
* @return the external name or null
|
||||||
|
*/
|
||||||
|
public NameXPtg getNameXPtg(String name, UDFFinder udf) {
|
||||||
|
LinkTable lnk = getOrCreateLinkTable();
|
||||||
|
NameXPtg xptg = lnk.getNameXPtg(name);
|
||||||
|
|
||||||
|
if(xptg == null && udf.findFunction(name) != null) {
|
||||||
|
// the name was not found in the list of external names
|
||||||
|
// check if the Workbook's UDFFinder is aware about it and register the name if it is
|
||||||
|
xptg = lnk.addNameXPtg(name);
|
||||||
|
}
|
||||||
|
return xptg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,9 +31,7 @@ import org.apache.poi.hssf.record.NameCommentRecord;
|
|||||||
import org.apache.poi.hssf.record.NameRecord;
|
import org.apache.poi.hssf.record.NameRecord;
|
||||||
import org.apache.poi.hssf.record.Record;
|
import org.apache.poi.hssf.record.Record;
|
||||||
import org.apache.poi.hssf.record.SupBookRecord;
|
import org.apache.poi.hssf.record.SupBookRecord;
|
||||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
import org.apache.poi.ss.formula.ptg.*;
|
||||||
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
|
||||||
import org.apache.poi.ss.formula.ptg.Ref3DPtg;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link Table (OOO pdf reference: 4.10.3 ) <p/>
|
* Link Table (OOO pdf reference: 4.10.3 ) <p/>
|
||||||
@ -92,7 +90,7 @@ final class LinkTable {
|
|||||||
|
|
||||||
private static final class ExternalBookBlock {
|
private static final class ExternalBookBlock {
|
||||||
private final SupBookRecord _externalBookRecord;
|
private final SupBookRecord _externalBookRecord;
|
||||||
private final ExternalNameRecord[] _externalNameRecords;
|
private ExternalNameRecord[] _externalNameRecords;
|
||||||
private final CRNBlock[] _crnBlocks;
|
private final CRNBlock[] _crnBlocks;
|
||||||
|
|
||||||
public ExternalBookBlock(RecordStream rs) {
|
public ExternalBookBlock(RecordStream rs) {
|
||||||
@ -113,12 +111,28 @@ final class LinkTable {
|
|||||||
temp.toArray(_crnBlocks);
|
temp.toArray(_crnBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new block for internal references. It is called when constructing a new LinkTable.
|
||||||
|
*
|
||||||
|
* @see org.apache.poi.hssf.model.LinkTable#LinkTable(int, WorkbookRecordList)
|
||||||
|
*/
|
||||||
public ExternalBookBlock(int numberOfSheets) {
|
public ExternalBookBlock(int numberOfSheets) {
|
||||||
_externalBookRecord = SupBookRecord.createInternalReferences((short)numberOfSheets);
|
_externalBookRecord = SupBookRecord.createInternalReferences((short)numberOfSheets);
|
||||||
_externalNameRecords = new ExternalNameRecord[0];
|
_externalNameRecords = new ExternalNameRecord[0];
|
||||||
_crnBlocks = new CRNBlock[0];
|
_crnBlocks = new CRNBlock[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new block for registering add-in functions
|
||||||
|
*
|
||||||
|
* @see org.apache.poi.hssf.model.LinkTable#addNameXPtg(String)
|
||||||
|
*/
|
||||||
|
public ExternalBookBlock() {
|
||||||
|
_externalBookRecord = SupBookRecord.createAddInFunctions();
|
||||||
|
_externalNameRecords = new ExternalNameRecord[0];
|
||||||
|
_crnBlocks = new CRNBlock[0];
|
||||||
|
}
|
||||||
|
|
||||||
public SupBookRecord getExternalBookRecord() {
|
public SupBookRecord getExternalBookRecord() {
|
||||||
return _externalBookRecord;
|
return _externalBookRecord;
|
||||||
}
|
}
|
||||||
@ -143,9 +157,21 @@ final class LinkTable {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNumberOfNames() {
|
||||||
|
return _externalNameRecords.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ExternalBookBlock[] _externalBookBlocks;
|
public int addExternalName(ExternalNameRecord rec){
|
||||||
|
ExternalNameRecord[] tmp = new ExternalNameRecord[_externalNameRecords.length + 1];
|
||||||
|
System.arraycopy(_externalNameRecords, 0, tmp, 0, _externalNameRecords.length);
|
||||||
|
tmp[tmp.length - 1] = rec;
|
||||||
|
_externalNameRecords = tmp;
|
||||||
|
return _externalNameRecords.length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExternalBookBlock[] _externalBookBlocks;
|
||||||
private final ExternSheetRecord _externSheetRecord;
|
private final ExternSheetRecord _externSheetRecord;
|
||||||
private final List<NameRecord> _definedNames;
|
private final List<NameRecord> _definedNames;
|
||||||
private final int _recordCount;
|
private final int _recordCount;
|
||||||
@ -461,6 +487,68 @@ final class LinkTable {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an external name in this workbook
|
||||||
|
*
|
||||||
|
* @param name the name to register
|
||||||
|
* @return a NameXPtg describing this name
|
||||||
|
*/
|
||||||
|
public NameXPtg addNameXPtg(String name) {
|
||||||
|
int extBlockIndex = -1;
|
||||||
|
ExternalBookBlock extBlock = null;
|
||||||
|
|
||||||
|
// find ExternalBlock for Add-In functions and remember its index
|
||||||
|
for (int i = 0; i < _externalBookBlocks.length; i++) {
|
||||||
|
SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord();
|
||||||
|
if (ebr.isAddInFunctions()) {
|
||||||
|
extBlock = _externalBookBlocks[i];
|
||||||
|
extBlockIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// An ExternalBlock for Add-In functions was not found. Create a new one.
|
||||||
|
if (extBlock == null) {
|
||||||
|
extBlock = new ExternalBookBlock();
|
||||||
|
|
||||||
|
ExternalBookBlock[] tmp = new ExternalBookBlock[_externalBookBlocks.length + 1];
|
||||||
|
System.arraycopy(_externalBookBlocks, 0, tmp, 0, _externalBookBlocks.length);
|
||||||
|
tmp[tmp.length - 1] = extBlock;
|
||||||
|
_externalBookBlocks = tmp;
|
||||||
|
|
||||||
|
extBlockIndex = _externalBookBlocks.length - 1;
|
||||||
|
|
||||||
|
// add the created SupBookRecord before ExternSheetRecord
|
||||||
|
int idx = findFirstRecordLocBySid(ExternSheetRecord.sid);
|
||||||
|
_workbookRecordList.add(idx, extBlock.getExternalBookRecord());
|
||||||
|
|
||||||
|
// register the SupBookRecord in the ExternSheetRecord
|
||||||
|
// -2 means that the scope of this name is Workbook and the reference applies to the entire workbook.
|
||||||
|
_externSheetRecord.addRef(_externalBookBlocks.length - 1, -2, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a ExternalNameRecord that will describe this name
|
||||||
|
ExternalNameRecord extNameRecord = new ExternalNameRecord();
|
||||||
|
extNameRecord.setText(name);
|
||||||
|
// The docs don't explain why Excel set the formula to #REF!
|
||||||
|
extNameRecord.setParsedExpression(new Ptg[]{ErrPtg.REF_INVALID});
|
||||||
|
|
||||||
|
int nameIndex = extBlock.addExternalName(extNameRecord);
|
||||||
|
int supLinkIndex = 0;
|
||||||
|
// find the posistion of the Add-In SupBookRecord in the workbook stream,
|
||||||
|
// the created ExternalNameRecord will be appended to it
|
||||||
|
for (Iterator iterator = _workbookRecordList.iterator(); iterator.hasNext(); supLinkIndex++) {
|
||||||
|
Record record = (Record) iterator.next();
|
||||||
|
if (record instanceof SupBookRecord) {
|
||||||
|
if (((SupBookRecord) record).isAddInFunctions()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int numberOfNames = extBlock.getNumberOfNames();
|
||||||
|
// a new name is inserted in the end of the SupBookRecord, after the last name
|
||||||
|
_workbookRecordList.add(supLinkIndex + numberOfNames, extNameRecord);
|
||||||
|
int ix = _externSheetRecord.getRefIxForSheet(extBlockIndex, -2 /* the scope is workbook*/);
|
||||||
|
return new NameXPtg(ix, nameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
private int findRefIndexFromExtBookIndex(int extBookIndex) {
|
private int findRefIndexFromExtBookIndex(int extBookIndex) {
|
||||||
return _externSheetRecord.findRefIndexFromExtBookIndex(extBookIndex);
|
return _externSheetRecord.findRefIndexFromExtBookIndex(extBookIndex);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import org.apache.poi.util.LittleEndianOutput;
|
|||||||
* @author Libin Roman (Vista Portal LDT. Developer)
|
* @author Libin Roman (Vista Portal LDT. Developer)
|
||||||
*/
|
*/
|
||||||
public class ExternSheetRecord extends StandardRecord {
|
public class ExternSheetRecord extends StandardRecord {
|
||||||
|
|
||||||
public final static short sid = 0x0017;
|
public final static short sid = 0x0017;
|
||||||
private List<RefSubRecord> _list;
|
private List<RefSubRecord> _list;
|
||||||
|
|
||||||
@ -184,6 +185,33 @@ public class ExternSheetRecord extends StandardRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add a zero-based reference to a {@link org.apache.poi.hssf.record.SupBookRecord}.
|
||||||
|
* <p>
|
||||||
|
* If the type of the SupBook record is same-sheet referencing, Add-In referencing,
|
||||||
|
* DDE data source referencing, or OLE data source referencing,
|
||||||
|
* then no scope is specified and this value <em>MUST</em> be -2. Otherwise,
|
||||||
|
* the scope must be set as follows:
|
||||||
|
* <ol>
|
||||||
|
* <li><code>-2</code> Workbook-level reference that applies to the entire workbook.</li>
|
||||||
|
* <li><code>-1</code> Sheet-level reference. </li>
|
||||||
|
* <li><code>>=0</code> Sheet-level reference. This specifies the first sheet in the reference.
|
||||||
|
* <p>
|
||||||
|
* If the SupBook type is unused or external workbook referencing,
|
||||||
|
* then this value specifies the zero-based index of an external sheet name,
|
||||||
|
* see {@link org.apache.poi.hssf.record.SupBookRecord#getSheetNames()}.
|
||||||
|
* This referenced string specifies the name of the first sheet within the external workbook that is in scope.
|
||||||
|
* This sheet MUST be a worksheet or macro sheet.
|
||||||
|
* <p>
|
||||||
|
* <p>
|
||||||
|
* If the supporting link type is self-referencing, then this value specifies the zero-based index of a
|
||||||
|
* {@link org.apache.poi.hssf.record.BoundSheetRecord} record in the workbook stream that specifies
|
||||||
|
* the first sheet within the scope of this reference. This sheet MUST be a worksheet or a macro sheet.
|
||||||
|
* </p>
|
||||||
|
* </li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* @param firstSheetIndex the scope, must be -2 for add-in references
|
||||||
|
* @param lastSheetIndex the scope, must be -2 for add-in references
|
||||||
* @return index of newly added ref
|
* @return index of newly added ref
|
||||||
*/
|
*/
|
||||||
public int addRef(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
|
public int addRef(int extBookIndex, int firstSheetIndex, int lastSheetIndex) {
|
||||||
|
@ -19,6 +19,7 @@ package org.apache.poi.hssf.record;
|
|||||||
|
|
||||||
import org.apache.poi.ss.formula.constant.ConstantValueParser;
|
import org.apache.poi.ss.formula.constant.ConstantValueParser;
|
||||||
import org.apache.poi.ss.formula.Formula;
|
import org.apache.poi.ss.formula.Formula;
|
||||||
|
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||||
import org.apache.poi.util.LittleEndianOutput;
|
import org.apache.poi.util.LittleEndianOutput;
|
||||||
import org.apache.poi.util.StringUtil;
|
import org.apache.poi.util.StringUtil;
|
||||||
|
|
||||||
@ -98,6 +99,10 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||||||
return field_4_name;
|
return field_4_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setText(String str) {
|
||||||
|
field_4_name = str;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this is a local name, then this is the (1 based)
|
* If this is a local name, then this is the (1 based)
|
||||||
* index of the name of the Sheet this refers to, as
|
* index of the name of the Sheet this refers to, as
|
||||||
@ -107,6 +112,17 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||||||
public short getIx() {
|
public short getIx() {
|
||||||
return field_2_ixals;
|
return field_2_ixals;
|
||||||
}
|
}
|
||||||
|
public void setIx(short ix) {
|
||||||
|
field_2_ixals = ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ptg[] getParsedExpression() {
|
||||||
|
return Formula.getTokens(field_5_name_definition);
|
||||||
|
}
|
||||||
|
public void setParsedExpression(Ptg[] ptgs) {
|
||||||
|
field_5_name_definition = Formula.create(ptgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected int getDataSize(){
|
protected int getDataSize(){
|
||||||
int result = 2 + 4; // short and int
|
int result = 2 + 4; // short and int
|
||||||
@ -142,6 +158,9 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExternalNameRecord() {
|
||||||
|
field_2_ixals = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public ExternalNameRecord(RecordInputStream in) {
|
public ExternalNameRecord(RecordInputStream in) {
|
||||||
field_1_option_flag = in.readShort();
|
field_1_option_flag = in.readShort();
|
||||||
@ -180,10 +199,15 @@ public final class ExternalNameRecord extends StandardRecord {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append("[EXTERNALNAME]\n");
|
sb.append("[EXTERNALNAME]\n");
|
||||||
|
sb.append(" .options = ").append(field_1_option_flag).append("\n");
|
||||||
sb.append(" .ix = ").append(field_2_ixals).append("\n");
|
sb.append(" .ix = ").append(field_2_ixals).append("\n");
|
||||||
sb.append(" .name = ").append(field_4_name).append("\n");
|
sb.append(" .name = ").append(field_4_name).append("\n");
|
||||||
if(field_5_name_definition != null) {
|
if(field_5_name_definition != null) {
|
||||||
sb.append(" .formula = ").append(field_5_name_definition).append("\n");
|
Ptg[] ptgs = field_5_name_definition.getTokens();
|
||||||
|
for (int i = 0; i < ptgs.length; i++) {
|
||||||
|
Ptg ptg = ptgs[i];
|
||||||
|
sb.append(ptg.toString()).append(ptg.getRVAType()).append("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sb.append("[/EXTERNALNAME]\n");
|
sb.append("[/EXTERNALNAME]\n");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
@ -359,7 +359,7 @@ public final class FormulaRecord extends CellRecord {
|
|||||||
sb.append(" .alwaysCalc= ").append(isAlwaysCalc()).append("\n");
|
sb.append(" .alwaysCalc= ").append(isAlwaysCalc()).append("\n");
|
||||||
sb.append(" .calcOnLoad= ").append(isCalcOnLoad()).append("\n");
|
sb.append(" .calcOnLoad= ").append(isCalcOnLoad()).append("\n");
|
||||||
sb.append(" .shared = ").append(isSharedFormula()).append("\n");
|
sb.append(" .shared = ").append(isSharedFormula()).append("\n");
|
||||||
sb.append(" .zero = ").append(HexDump.intToHex(field_6_zero));
|
sb.append(" .zero = ").append(HexDump.intToHex(field_6_zero)).append("\n");
|
||||||
|
|
||||||
Ptg[] ptgs = field_8_parsed_expr.getTokens();
|
Ptg[] ptgs = field_8_parsed_expr.getTokens();
|
||||||
for (int k = 0; k < ptgs.length; k++ ) {
|
for (int k = 0; k < ptgs.length; k++ ) {
|
||||||
|
@ -47,7 +47,7 @@ public final class SupBookRecord extends StandardRecord {
|
|||||||
return new SupBookRecord(false, numberOfSheets);
|
return new SupBookRecord(false, numberOfSheets);
|
||||||
}
|
}
|
||||||
public static SupBookRecord createAddInFunctions() {
|
public static SupBookRecord createAddInFunctions() {
|
||||||
return new SupBookRecord(true, (short)0);
|
return new SupBookRecord(true, (short)1 /* this field MUST be 0x0001 for add-in referencing */);
|
||||||
}
|
}
|
||||||
public static SupBookRecord createExternalReferences(String url, String[] sheetNames) {
|
public static SupBookRecord createExternalReferences(String url, String[] sheetNames) {
|
||||||
return new SupBookRecord(url, sheetNames);
|
return new SupBookRecord(url, sheetNames);
|
||||||
|
@ -33,6 +33,7 @@ import org.apache.poi.ss.formula.FormulaParseException;
|
|||||||
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
|
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
|
||||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||||
import org.apache.poi.ss.formula.FormulaType;
|
import org.apache.poi.ss.formula.FormulaType;
|
||||||
|
import org.apache.poi.ss.formula.udf.UDFFinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal POI use only
|
* Internal POI use only
|
||||||
@ -65,7 +66,9 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NameXPtg getNameXPtg(String name) {
|
public NameXPtg getNameXPtg(String name) {
|
||||||
return _iBook.getNameXPtg(name);
|
// TODO YK: passing UDFFinder.DEFAULT is temporary,
|
||||||
|
// a proper design should take it from the parent HSSFWorkbook
|
||||||
|
return _iBook.getNameXPtg(name, UDFFinder.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1679,12 +1679,4 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss
|
|||||||
private static byte[] newUID() {
|
private static byte[] newUID() {
|
||||||
return new byte[16];
|
return new byte[16];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Note - This method should only used by POI internally.
|
|
||||||
* It may get deleted or change definition in future POI versions
|
|
||||||
*/
|
|
||||||
public NameXPtg getNameXPtg(String name) {
|
|
||||||
return workbook.getNameXPtg(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,12 @@ import junit.framework.AssertionFailedError;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.poi.hssf.HSSFTestDataSamples;
|
import org.apache.poi.hssf.HSSFTestDataSamples;
|
||||||
import org.apache.poi.hssf.record.NameCommentRecord;
|
import org.apache.poi.hssf.record.*;
|
||||||
import org.apache.poi.hssf.record.NameRecord;
|
|
||||||
import org.apache.poi.hssf.record.Record;
|
|
||||||
import org.apache.poi.hssf.record.SSTRecord;
|
|
||||||
import org.apache.poi.hssf.record.SupBookRecord;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.hssf.usermodel.TestHSSFWorkbook;
|
||||||
|
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link LinkTable}
|
* Tests for {@link LinkTable}
|
||||||
*
|
*
|
||||||
@ -179,4 +178,86 @@ public final class TestLinkTable extends TestCase {
|
|||||||
|
|
||||||
assertEquals(2, lt.getNumNames());
|
assertEquals(2, lt.getNumNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAddNameX(){
|
||||||
|
WorkbookRecordList wrl = new WorkbookRecordList();
|
||||||
|
wrl.add(0, new BOFRecord());
|
||||||
|
wrl.add(1, new CountryRecord());
|
||||||
|
wrl.add(2, EOFRecord.instance);
|
||||||
|
|
||||||
|
int numberOfSheets = 3;
|
||||||
|
LinkTable tbl = new LinkTable(numberOfSheets, wrl);
|
||||||
|
// creation of a new LinkTable insert two new records: SupBookRecord followed by ExternSheetRecord
|
||||||
|
// assure they are in place:
|
||||||
|
// [BOFRecord]
|
||||||
|
// [CountryRecord]
|
||||||
|
// [SUPBOOK Internal References nSheets= 3]
|
||||||
|
// [EXTERNSHEET]
|
||||||
|
// [EOFRecord]
|
||||||
|
|
||||||
|
assertEquals(5, wrl.getRecords().size());
|
||||||
|
assertTrue(wrl.get(2) instanceof SupBookRecord);
|
||||||
|
SupBookRecord sup1 = (SupBookRecord)wrl.get(2);
|
||||||
|
assertEquals(numberOfSheets, sup1.getNumberOfSheets());
|
||||||
|
assertTrue(wrl.get(3) instanceof ExternSheetRecord);
|
||||||
|
ExternSheetRecord extSheet = (ExternSheetRecord)wrl.get(3);
|
||||||
|
assertEquals(0, extSheet.getNumOfRefs());
|
||||||
|
|
||||||
|
assertNull(tbl.getNameXPtg("ISODD"));
|
||||||
|
assertEquals(5, wrl.getRecords().size()); //still have five records
|
||||||
|
|
||||||
|
NameXPtg namex1 = tbl.addNameXPtg("ISODD"); // adds two new rercords
|
||||||
|
assertEquals(0, namex1.getSheetRefIndex());
|
||||||
|
assertEquals(0, namex1.getNameIndex());
|
||||||
|
assertEquals(namex1.toString(), tbl.getNameXPtg("ISODD").toString());
|
||||||
|
// assure they are in place:
|
||||||
|
// [BOFRecord]
|
||||||
|
// [CountryRecord]
|
||||||
|
// [SUPBOOK Internal References nSheets= 3]
|
||||||
|
// [SUPBOOK Add-In Functions nSheets= 1]
|
||||||
|
// [EXTERNALNAME .name = ISODD]
|
||||||
|
// [EXTERNSHEET]
|
||||||
|
// [EOFRecord]
|
||||||
|
|
||||||
|
assertEquals(7, wrl.getRecords().size());
|
||||||
|
assertTrue(wrl.get(3) instanceof SupBookRecord);
|
||||||
|
SupBookRecord sup2 = (SupBookRecord)wrl.get(3);
|
||||||
|
assertTrue(sup2.isAddInFunctions());
|
||||||
|
assertTrue(wrl.get(4) instanceof ExternalNameRecord);
|
||||||
|
ExternalNameRecord ext1 = (ExternalNameRecord)wrl.get(4);
|
||||||
|
assertEquals("ISODD", ext1.getText());
|
||||||
|
assertTrue(wrl.get(5) instanceof ExternSheetRecord);
|
||||||
|
assertEquals(1, extSheet.getNumOfRefs());
|
||||||
|
|
||||||
|
//check that
|
||||||
|
assertEquals(0, tbl.resolveNameXIx(namex1.getSheetRefIndex(), namex1.getNameIndex()));
|
||||||
|
assertEquals("ISODD", tbl.resolveNameXText(namex1.getSheetRefIndex(), namex1.getNameIndex()));
|
||||||
|
|
||||||
|
assertNull(tbl.getNameXPtg("ISEVEN"));
|
||||||
|
NameXPtg namex2 = tbl.addNameXPtg("ISEVEN"); // adds two new rercords
|
||||||
|
assertEquals(0, namex2.getSheetRefIndex());
|
||||||
|
assertEquals(1, namex2.getNameIndex()); // name index increased by one
|
||||||
|
assertEquals(namex2.toString(), tbl.getNameXPtg("ISEVEN").toString());
|
||||||
|
assertEquals(8, wrl.getRecords().size());
|
||||||
|
// assure they are in place:
|
||||||
|
// [BOFRecord]
|
||||||
|
// [CountryRecord]
|
||||||
|
// [SUPBOOK Internal References nSheets= 3]
|
||||||
|
// [SUPBOOK Add-In Functions nSheets= 1]
|
||||||
|
// [EXTERNALNAME .name = ISODD]
|
||||||
|
// [EXTERNALNAME .name = ISEVEN]
|
||||||
|
// [EXTERNSHEET]
|
||||||
|
// [EOFRecord]
|
||||||
|
assertTrue(wrl.get(3) instanceof SupBookRecord);
|
||||||
|
assertTrue(wrl.get(4) instanceof ExternalNameRecord);
|
||||||
|
assertTrue(wrl.get(5) instanceof ExternalNameRecord);
|
||||||
|
assertEquals("ISODD", ((ExternalNameRecord)wrl.get(4)).getText());
|
||||||
|
assertEquals("ISEVEN", ((ExternalNameRecord)wrl.get(5)).getText());
|
||||||
|
assertTrue(wrl.get(6) instanceof ExternSheetRecord);
|
||||||
|
assertTrue(wrl.get(7) instanceof EOFRecord);
|
||||||
|
|
||||||
|
assertEquals(0, tbl.resolveNameXIx(namex2.getSheetRefIndex(), namex2.getNameIndex()));
|
||||||
|
assertEquals("ISEVEN", tbl.resolveNameXText(namex2.getSheetRefIndex(), namex2.getNameIndex()));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,13 @@ import junit.framework.TestCase;
|
|||||||
import org.apache.poi.hssf.record.FontRecord;
|
import org.apache.poi.hssf.record.FontRecord;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.hssf.usermodel.TestHSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.TestHSSFWorkbook;
|
||||||
|
import org.apache.poi.ss.formula.udf.UDFFinder;
|
||||||
|
import org.apache.poi.ss.formula.udf.DefaultUDFFinder;
|
||||||
|
import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
|
||||||
|
import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||||
|
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||||
|
import org.apache.poi.ss.formula.eval.NotImplementedException;
|
||||||
|
import org.apache.poi.ss.formula.OperationEvaluationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit test for the Workbook class.
|
* Unit test for the Workbook class.
|
||||||
@ -83,4 +90,28 @@ public final class TestWorkbook extends TestCase {
|
|||||||
assertEquals(6, wb.getFontIndex(n7));
|
assertEquals(6, wb.getFontIndex(n7));
|
||||||
assertEquals(n7, wb.getFontRecordAt(6));
|
assertEquals(n7, wb.getFontRecordAt(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAddNameX(){
|
||||||
|
InternalWorkbook wb = TestHSSFWorkbook.getInternalWorkbook(new HSSFWorkbook());
|
||||||
|
assertNotNull(wb.getNameXPtg("ISODD", UDFFinder.DEFAULT));
|
||||||
|
|
||||||
|
FreeRefFunction NotImplemented = new FreeRefFunction() {
|
||||||
|
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
|
||||||
|
throw new RuntimeException("not implemented");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* register the two test UDFs in a UDF finder, to be passed to the evaluator
|
||||||
|
*/
|
||||||
|
UDFFinder udff1 = new DefaultUDFFinder(new String[] { "myFunc", },
|
||||||
|
new FreeRefFunction[] { NotImplemented });
|
||||||
|
UDFFinder udff2 = new DefaultUDFFinder(new String[] { "myFunc2", },
|
||||||
|
new FreeRefFunction[] { NotImplemented });
|
||||||
|
UDFFinder udff = new AggregatingUDFFinder(udff1, udff2);
|
||||||
|
assertNotNull(wb.getNameXPtg("myFunc", udff));
|
||||||
|
assertNotNull(wb.getNameXPtg("myFunc2", udff));
|
||||||
|
|
||||||
|
assertNull(wb.getNameXPtg("myFunc3", udff)); // myFunc3 is unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,4 +103,11 @@ public final class TestSupBookRecord extends TestCase {
|
|||||||
|
|
||||||
TestcaseRecordInputStream.confirmRecordEncoding(0x01AE, dataER, record.serialize());
|
TestcaseRecordInputStream.confirmRecordEncoding(0x01AE, dataER, record.serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testStoreAIF() {
|
||||||
|
SupBookRecord record = SupBookRecord.createAddInFunctions();
|
||||||
|
assertEquals(1, record.getNumberOfSheets());
|
||||||
|
assertTrue(record.isAddInFunctions());
|
||||||
|
TestcaseRecordInputStream.confirmRecordEncoding(0x01AE, dataAIF, record.serialize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user