Author: yegor
Date: Sat Nov 27 06:30:03 2010
New Revision: 1039621

URL: http://svn.apache.org/viewvc?rev=1039621&view=rev
Log:
improved LinkTable to support registering external UDFs.

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
    poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java
    poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestLinkTable.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestWorkbook.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/TestSupBookRecord.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java Sat Nov 
27 06:30:03 2010
@@ -83,6 +83,7 @@ import org.apache.poi.hssf.record.WriteP
 import org.apache.poi.hssf.record.common.UnicodeString;
 import org.apache.poi.ss.formula.ptg.NameXPtg;
 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.hssf.util.HSSFColor;
 import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
@@ -2300,8 +2301,22 @@ public final class InternalWorkbook {
         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;
     }
 
     /**

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/LinkTable.java Sat Nov 27 
06:30:03 2010
@@ -31,9 +31,7 @@ import org.apache.poi.hssf.record.NameCo
 import org.apache.poi.hssf.record.NameRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.SupBookRecord;
-import org.apache.poi.ss.formula.ptg.Area3DPtg;
-import org.apache.poi.ss.formula.ptg.NameXPtg;
-import org.apache.poi.ss.formula.ptg.Ref3DPtg;
+import org.apache.poi.ss.formula.ptg.*;
 
 /**
  * Link Table (OOO pdf reference: 4.10.3 ) <p/>
@@ -92,7 +90,7 @@ final class LinkTable {
 
        private static final class ExternalBookBlock {
                private final SupBookRecord _externalBookRecord;
-               private final ExternalNameRecord[] _externalNameRecords;
+               private ExternalNameRecord[] _externalNameRecords;
                private final CRNBlock[] _crnBlocks;
 
                public ExternalBookBlock(RecordStream rs) {
@@ -113,12 +111,28 @@ final class LinkTable {
                        temp.toArray(_crnBlocks);
                }
 
-               public ExternalBookBlock(int numberOfSheets) {
+        /**
+         * 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) {
                        _externalBookRecord = 
SupBookRecord.createInternalReferences((short)numberOfSheets);
                        _externalNameRecords = new ExternalNameRecord[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() {
                        return _externalBookRecord;
                }
@@ -143,9 +157,21 @@ final class LinkTable {
                        }
                        return -1;
                }
-       }
 
-       private final ExternalBookBlock[] _externalBookBlocks;
+        public int getNumberOfNames() {
+            return _externalNameRecords.length;
+        }
+
+        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 List<NameRecord> _definedNames;
        private final int _recordCount;
@@ -461,7 +487,69 @@ final class LinkTable {
                return null;
        }
 
-       private int findRefIndexFromExtBookIndex(int extBookIndex) {
+    /**
+     * 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) {
                return 
_externSheetRecord.findRefIndexFromExtBookIndex(extBookIndex);
        }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java Sat 
Nov 27 06:30:03 2010
@@ -29,7 +29,8 @@ import org.apache.poi.util.LittleEndianO
  * @author Libin Roman (Vista Portal LDT. Developer)
  */
 public class ExternSheetRecord extends StandardRecord {
-       public final static short sid = 0x0017;
+
+    public final static short sid = 0x0017;
        private List<RefSubRecord> _list;
        
        private static final class RefSubRecord {
@@ -184,6 +185,33 @@ public class ExternSheetRecord extends S
        }
 
        /**
+     * 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>&gt;=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
         */
        public int addRef(int extBookIndex, int firstSheetIndex, int 
lastSheetIndex) {

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java Sat 
Nov 27 06:30:03 2010
@@ -19,6 +19,7 @@ package org.apache.poi.hssf.record;
 
 import org.apache.poi.ss.formula.constant.ConstantValueParser;
 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.StringUtil;
 
@@ -98,6 +99,10 @@ public final class ExternalNameRecord ex
                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)
         *  index of the name of the Sheet this refers to, as
@@ -107,6 +112,17 @@ public final class ExternalNameRecord ex
        public short getIx() {
           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(){
                int result = 2 + 4;  // short and int
@@ -142,8 +158,11 @@ public final class ExternalNameRecord ex
         }
        }
 
-
-       public ExternalNameRecord(RecordInputStream in) {
+    public ExternalNameRecord() {
+        field_2_ixals = 0;
+    }
+    
+    public ExternalNameRecord(RecordInputStream in) {
                field_1_option_flag = in.readShort();
                field_2_ixals       = in.readShort();
       field_3_not_used    = in.readShort();
@@ -180,10 +199,15 @@ public final class ExternalNameRecord ex
        public String toString() {
                StringBuffer sb = new StringBuffer();
                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("    .name    = ").append(field_4_name).append("\n");
                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");
                return sb.toString();

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java Sat Nov 27 
06:30:03 2010
@@ -359,7 +359,7 @@ public final class FormulaRecord extends
                sb.append("    .alwaysCalc= 
").append(isAlwaysCalc()).append("\n");
                sb.append("    .calcOnLoad= 
").append(isCalcOnLoad()).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();
                for (int k = 0; k < ptgs.length; k++ ) {

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/SupBookRecord.java Sat Nov 27 
06:30:03 2010
@@ -47,7 +47,7 @@ public final class SupBookRecord extends
         return new SupBookRecord(false, numberOfSheets);
     }
     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) {
         return new SupBookRecord(url, sheetNames);

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java 
Sat Nov 27 06:30:03 2010
@@ -33,6 +33,7 @@ import org.apache.poi.ss.formula.Formula
 import org.apache.poi.ss.formula.FormulaParsingWorkbook;
 import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
 import org.apache.poi.ss.formula.FormulaType;
+import org.apache.poi.ss.formula.udf.UDFFinder;
 
 /**
  * Internal POI use only
@@ -65,7 +66,9 @@ public final class HSSFEvaluationWorkboo
        }
 
        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);
        }
 
        /**

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Sat Nov 
27 06:30:03 2010
@@ -1679,12 +1679,4 @@ public final class HSSFWorkbook extends 
     private static byte[] newUID() {
         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);
-    }
 }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestLinkTable.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestLinkTable.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestLinkTable.java 
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestLinkTable.java Sat 
Nov 27 06:30:03 2010
@@ -27,13 +27,12 @@ import junit.framework.AssertionFailedEr
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
-import org.apache.poi.hssf.record.NameCommentRecord;
-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.record.*;
 import org.apache.poi.hssf.usermodel.HSSFCell;
 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}
  *
@@ -179,4 +178,86 @@ public final class TestLinkTable extends
 
     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()));
+
+    }
 }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestWorkbook.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestWorkbook.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestWorkbook.java 
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestWorkbook.java Sat Nov 
27 06:30:03 2010
@@ -22,6 +22,13 @@ import junit.framework.TestCase;
 import org.apache.poi.hssf.record.FontRecord;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 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.
@@ -83,4 +90,28 @@ public final class TestWorkbook extends 
                assertEquals(6, wb.getFontIndex(n7));
                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
+    }
 }

Modified: 
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestSupBookRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestSupBookRecord.java?rev=1039621&r1=1039620&r2=1039621&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/TestSupBookRecord.java 
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/TestSupBookRecord.java 
Sat Nov 27 06:30:03 2010
@@ -102,5 +102,12 @@ public final class TestSupBookRecord ext
         SupBookRecord record = SupBookRecord.createExternalReferences(url, 
sheetNames);
 
         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());
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to