You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by ac...@apache.org on 2003/07/19 04:48:17 UTC

cvs commit: jakarta-poi/src/java/org/apache/poi/hssf/record FormulaRecord.java

acoliver    2003/07/18 19:48:17

  Modified:    src/java/org/apache/poi/hssf/record/aggregates
                        RowRecordsAggregate.java ValueRecordsAggregate.java
               .        .classpath
               src/java/org/apache/poi/hssf/usermodel HSSFSheet.java
                        HSSFRow.java HSSFWorkbook.java HSSFCell.java
               src/java/org/apache/poi/hssf/model Sheet.java
               src/java/org/apache/poi/hssf/record FormulaRecord.java
  Log:
  Beginnings of the performance-branch merge.
  CVS: ----------------------------------------------------------------------
  CVS: PR:
  CVS:   If this change addresses a PR in the problem report tracking
  CVS:   database, then enter the PR number(s) here.
  CVS: Obtained from:
  CVS:   If this change has been taken from another system, such as NCSA,
  CVS:   then name the system in this line, otherwise delete it.
  CVS: Submitted by:
  CVS:   If this code has been contributed to Apache by someone else; i.e.,
  CVS:   they sent us a patch or a new module, then include their name/email
  CVS:   address here. If this is your work then delete this line.
  CVS: Reviewed by:
  CVS:   If we are doing pre-commit code reviews and someone else has
  CVS:   reviewed your changes, include their name(s) here.
  CVS:   If you have not had it reviewed then delete this line.
  
  Revision  Changes    Path
  1.7       +54 -7     jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java
  
  Index: RowRecordsAggregate.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- RowRecordsAggregate.java	9 May 2003 12:39:08 -0000	1.6
  +++ RowRecordsAggregate.java	19 Jul 2003 02:48:16 -0000	1.7
  @@ -2,7 +2,7 @@
   /* ====================================================================
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2003 The Apache Software Foundation.  All rights
  + * Copyright (c) 2002 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -75,10 +75,12 @@
   {
       int     firstrow = -1;
       int     lastrow  = -1;
  +    boolean firstdirty = false;
  +    boolean lastdirty  = false;
       Map records  = null;
       int     size     = 0;
   
  -    /** Creates a new instance of ValueRecordsAggregate */
  +    /** Creates a new instance of RowRecordsAggregate */
   
       public RowRecordsAggregate()
       {
  @@ -107,6 +109,12 @@
           size -= row.getRecordSize();
   
           // Integer integer = new Integer(row.getRowNumber());
  +        if (lastrow == row.getRowNumber()) {
  +            lastdirty = true;
  +        }
  +        if (firstrow == row.getRowNumber()) {
  +            firstdirty = true;
  +        }
           records.remove(row);
       }
   
  @@ -127,17 +135,20 @@
   
       public int getFirstRowNum()
       {
  +        if (firstdirty) {
  +            firstrow = findFirstRow();
  +        }
           return firstrow;
       }
   
       public int getLastRowNum()
       {
  +        if (lastdirty) {
  +            lastrow = findLastRow();
  +        }
           return lastrow;
       }
   
  -	/*
  -	 * No need to go through all the records as we're just collecting RowRecords 
  -
       public int construct(int offset, List records)
       {
           int k = 0;
  @@ -157,7 +168,7 @@
           }
           return k;
       }
  -	*/
  +
       /**
        * called by the class that is responsible for writing this sucker.
        * Subclasses should implement this so that their data is passed back in a
  @@ -222,7 +233,43 @@
       {
           return records.values().iterator();
       }
  -    
  +
  +    /**
  +     * used internally to refresh the "last row" when the last row is removed.
  +     */
  +    private int findLastRow()
  +    {
  +        int rownum = lastrow-1;
  +        RowRecord r = getRow(rownum);
  +
  +        while (r == null && rownum >= 0)
  +        {
  +            r = this.getRow(--rownum);
  +        }
  +        return rownum;
  +    }
  +
  +    /**
  +     * used internally to refresh the "first row" when the first row is removed.
  +     */
  +
  +    private int findFirstRow()
  +    {
  +        int rownum = firstrow+1;
  +        RowRecord r = getRow(rownum);
  +
  +        while (r == null && rownum <= getLastRowNum())
  +        {
  +            r = getRow(++rownum);
  +        }
  +
  +        if (rownum > getLastRowNum())
  +            return -1;
  +
  +        return rownum;
  +    }
  +
  +
       /** Performs a deep clone of the record*/
       public Object clone() {
         RowRecordsAggregate rec = new RowRecordsAggregate();
  
  
  
  1.9       +479 -161  jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java
  
  Index: ValueRecordsAggregate.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ValueRecordsAggregate.java	8 May 2003 00:02:03 -0000	1.8
  +++ ValueRecordsAggregate.java	19 Jul 2003 02:48:16 -0000	1.9
  @@ -2,7 +2,7 @@
   /* ====================================================================
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 2003 The Apache Software Foundation.  All rights
  + * Copyright (c) 2002 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -55,17 +55,22 @@
   
   package org.apache.poi.hssf.record.aggregates;
   
  +import org.apache.poi.hssf.usermodel.HSSFCell; //kludge shouldn't refer to this
  +
   import org.apache.poi.hssf.record.*;
  +import org.apache.poi.hssf.record.formula.Ptg;
  +import org.apache.poi.util.DoubleList;
  +import org.apache.poi.util.IntList;
   
   import java.util.Iterator;
   import java.util.List;
  -import java.util.TreeMap;
  +import java.util.ArrayList;
   
   /**
    *
    * Aggregate value records together.  Things are easier to handle that way.
    *
  - * @author  andy
  + * @author  Andrew C. Oliver
    * @author  Glen Stampoultzis (glens at apache.org)
    * @author Jason Height (jheight at chariot dot net dot au)
    */
  @@ -76,64 +81,73 @@
       public final static short sid       = -1000;
       int                       firstcell = -1;
       int                       lastcell  = -1;
  -    TreeMap                   records   = null;
  -//    int                       size      = 0;
  +    //TreeMap                   records   = null;
   
  -    /** Creates a new instance of ValueRecordsAggregate */
  +    private final static int DEFAULT_ROWS=10000;
  +    private final static int DEFAULT_COLS=256;
  +
  +    List celltype = null;
  +    List xfs      = null;
  +    List numericcells = null;
  +    List formulaptgs = null;
  +    List stringvals = null;
  +    IntList populatedRows = null;
  +    int physCells; //physical number of cells
  +
  +    public CellValueRecordInterface getCell(int row, short col) {
  +        return constructRecord(row, col);
   
  -    public ValueRecordsAggregate()
  -    {
  -        records = new TreeMap();
       }
   
  -    public void insertCell(CellValueRecordInterface cell)
  -    {
  -/*        if (records.get(cell) == null)
  -        {
  -            size += (( Record ) cell).getRecordSize();
  -        }
  -        else
  -        {
  -            size += (( Record ) cell).getRecordSize()
  -                    - (( Record ) records.get(cell)).getRecordSize();
  -        }*/
  +    public int getRecordSize() {
  +        //throw new RuntimeException("Not Implemented getRecordSize");
   
  -        // XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn());
  -        Object o = records.put(cell, cell);
  +        int size = 0;
  +        Iterator irecs = getIterator();
   
  -        if ((cell.getColumn() < firstcell) || (firstcell == -1))
  -        {
  -            firstcell = cell.getColumn();
  -        }
  -        if ((cell.getColumn() > lastcell) || (lastcell == -1))
  -        {
  -            lastcell = cell.getColumn();
  +        while (irecs.hasNext()) {
  +                size += (( Record ) irecs.next()).getRecordSize();
           }
  +
  +        return size;
  +//        return size;
       }
   
  -    public void removeCell(CellValueRecordInterface cell)
  +    public int serialize(int offset, byte [] data)
       {
  -  //      size -= (( Record ) cell).getRecordSize();
  +        //throw new RuntimeException("Not Implemented serialize");
  +        int      pos = offset;
  +        Iterator irecs = getIterator();
   
  -        // XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn());
  -        records.remove(cell);
  -    }
  +        while (irecs.hasNext()) {
  +                pos += (( Record ) irecs.next()).serialize(pos,data);
  +        }
   
  -    public int getPhysicalNumberOfCells()
  -    {
  -        return records.size();
  +/*        Iterator itr = records.values().iterator();
  +        int      pos = offset;
  +
  +        while (itr.hasNext())
  +        {
  +            pos += (( Record ) itr.next()).serialize(pos, data);
  +        }*/
  +        return pos - offset;
       }
   
  -    public int getFirstCellNum()
  -    {
  -        return firstcell;
  +    public ValueRecordsAggregate() {
  +        celltype = new ArrayList(DEFAULT_ROWS);
  +        xfs      = new ArrayList(DEFAULT_ROWS);
  +        numericcells = new ArrayList(DEFAULT_ROWS);
  +        formulaptgs  = new ArrayList(DEFAULT_ROWS);
  +        stringvals   = new ArrayList(DEFAULT_ROWS);
  +        populatedRows = new IntList(DEFAULT_ROWS);
  +        physCells = 0;
       }
   
  -    public int getLastCellNum()
  -    {
  -        return lastcell;
  +    public Iterator getIterator() {
  +      return new VRAIterator(this);
       }
   
  +
       public int construct(int offset, List records)
       {
           int k = 0;
  @@ -157,11 +171,6 @@
               {
                   lastFormulaAggregate.setStringRecord((StringRecord)rec);
               }
  -            else if (rec instanceof SharedFormulaRecord)
  -            {
  -            	//these follow the first formula in a group
  -            	lastFormulaAggregate.setSharedFormulaRecord((SharedFormulaRecord)rec);
  -            }
               else if (rec.isValue())
               {
                   insertCell(( CellValueRecordInterface ) rec);
  @@ -170,140 +179,449 @@
           return k;
       }
   
  -    /**
  -     * called by the class that is responsible for writing this sucker.
  -     * Subclasses should implement this so that their data is passed back in a
  -     * byte array.
  -     *
  -     * @param offset to begin writing at
  -     * @param data byte array containing instance data
  -     * @return number of bytes written
  -     */
  +    public int getPhysicalNumberOfCells() {
  +        return physCells;
  +    }
   
  -    public int serialize(int offset, byte [] data)
  +    public int getPhysicalNumberOfCellsInRow(int row) {
  +        int count = -1;
  +        int col = -1;
  +        boolean firsttime = true;
  +
  +        while (col > 0 || count == -1) {
  +            col = findNextPopulatedCell(row,col);
  +            count++;
  +        }
  +        return count;
  +    }
  +
  +    public void setValue(int row, short cell, double val) {
  +        ((DoubleList)numericcells.get(row)).set(cell, val);
  +    }
  +
  +    public void setStyle(int row, short cell, short xf) {
  +        ((IntList)xfs.get(row)).set(cell, xf);
  +    }
  +
  +
  +    public Iterator getRowCellIterator(int row) {
  +        return new VRAIterator(this, row);
  +    }
  +
  +    public void removeRow(int row) {
  +        Iterator iterator = this.getRowCellIterator(row);
  +        while(iterator.hasNext()) {
  +            iterator.next();
  +            iterator.remove();
  +        }
  +    }
  +
  +    public void removeCell(CellValueRecordInterface cell) {
  +        int rownum = cell.getRow();
  +        int colnum = cell.getColumn();
  +        int xf     = cell.getXFIndex();
  +        int type   = determineType(cell);
  +
  +        if (rownum < celltype.size() && colnum < ((IntList)celltype.get(rownum)).size()) {
  +            IntList ctRow = (IntList)celltype.get(rownum);
  +            if (ctRow.size()-1 == colnum) {
  +                ctRow.remove(colnum);
  +                if (ctRow.size() == 0 && celltype.size()-1 == rownum) {
  +                    celltype.remove(rownum);
  +                    int remp = populatedRows.indexOf(rownum);
  +                    System.err.println("remp == "+remp);
  +                    populatedRows.removeValue(rownum);
  +                }
  +            } else {
  +                ctRow.set(colnum,-1);
  +            }
  +            physCells--;
  +        } else {
  +          //this cell doesn't exist...
  +            throw new RuntimeException("Tried to remove a cell that does not exist r,c="+rownum+","+colnum);
  +        }
  +    }
  +
  +    public void insertCell(CellValueRecordInterface cell) {
  +        int rownum = cell.getRow();
  +        int colnum = cell.getColumn();
  +        int xf     = cell.getXFIndex();
  +        int type   = determineType(cell);
  +
  +        if (celltype.size() < rownum+1) {
  +            populatedRows.add(rownum); //this means we must never have had this row inserted
  +        }
  +
  +        ensureRows(rownum);
  +
  +        IntList ctRow = (IntList)celltype.get(rownum);
  +        IntList xfRow = (IntList)xfs.get(rownum);
  +
  +
  +        adjustIntList(ctRow, colnum+1);
  +        adjustIntList(xfRow, colnum+1);
  +
  +        ctRow.set(colnum, type);
  +        xfRow.set(colnum, xf);
  +
  +        insertCell(cell, type);
  +    }
  +
  +    CellValueRecordInterface constructRecord(int row, int col) {
  +        if (celltype.size() < row || ((IntList)celltype.get(row)).size() < col) {
  +            throw new ArrayIndexOutOfBoundsException("constructRecord called with row = "+row+
  +                      "and col ="+col+" but there are only "+celltype.size()+" rows and "+
  +                      ((IntList)celltype.get(row)).size()+" cols!!");
  +        }
  +
  +        CellValueRecordInterface retval = null;
  +        int type = ((IntList)celltype.get(row)).get(col);
  +
  +
  +        switch (type) {
  +            case HSSFCell.CELL_TYPE_NUMERIC:
  +                NumberRecord nrecord = new NumberRecord();
  +                nrecord.setColumn((short)col);
  +                nrecord.setRow(row);
  +                nrecord.setValue(((DoubleList)numericcells.get(row)).get(col));
  +                nrecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
  +                retval = nrecord;
  +                break;
  +            case HSSFCell.CELL_TYPE_STRING:
  +                LabelSSTRecord srecord = new LabelSSTRecord();
  +                srecord.setColumn((short)col);
  +                srecord.setRow(row);
  +                srecord.setSSTIndex((int)((DoubleList)numericcells.get(row)).get(col));
  +                srecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
  +                retval=srecord;
  +                break;
  +            case HSSFCell.CELL_TYPE_BLANK:
  +                BlankRecord brecord = new BlankRecord();
  +                brecord.setColumn((short)col);
  +                brecord.setRow(row);
  +                brecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
  +                retval=brecord;
  +                break;
  +            case HSSFCell.CELL_TYPE_FORMULA:
  +                FormulaRecord fr = new FormulaRecord();
  +                fr.setColumn((short)col);
  +                fr.setOptions((short)2);
  +
  +                fr.setRow(row);
  +                fr.setXFIndex((short)((IntList)xfs.get(row)).get(col));
  +                StringRecord        st = null;
  +                String strval = (String)((List)stringvals.get(row)).get(col);
  +                List expressionlist =  (List)((List)formulaptgs.get(row)).get(col);
  +                fr.setParsedExpression(expressionlist);
  +                fr.setExpressionLength(calculatePtgSize(expressionlist));
  +                if (strval != null) {
  +                  st = new StringRecord();
  +                   st.setString(strval);
  +                }
  +                FormulaRecordAggregate frarecord = new FormulaRecordAggregate(fr,st);
  +
  +                retval= frarecord;
  +                break;
  +
  +            default:
  +                throw new RuntimeException("UnImplemented Celltype "+type);
  +        }
  +
  +        return retval;
  +    }
  +
  +    private short calculatePtgSize(List expressionlist) {
  +        short retval = 0;
  +        Iterator iter = expressionlist.iterator();
  +        while (iter.hasNext()) {
  +            retval += (short)((Ptg)iter.next()).getSize();
  +        }
  +        return retval;
  +    }
  +
  +    private void insertCell(CellValueRecordInterface cell, int type) {
  +        int rownum = cell.getRow();
  +        int colnum = cell.getColumn();
  +
  +        DoubleList  nmRow = (DoubleList)numericcells.get(rownum);
  +
  +        switch (type) {
  +            case HSSFCell.CELL_TYPE_NUMERIC:
  +                NumberRecord nrecord = (NumberRecord)cell;
  +                adjustDoubleList(nmRow, colnum+1);
  +                nmRow.set(colnum,nrecord.getValue());
  +                physCells++;
  +                break;
  +            case HSSFCell.CELL_TYPE_STRING:
  +                LabelSSTRecord srecord = (LabelSSTRecord)cell;
  +                adjustDoubleList(nmRow, colnum+1);
  +                nmRow.set(colnum,srecord.getSSTIndex());
  +                physCells++;
  +                break;
  +            case HSSFCell.CELL_TYPE_FORMULA:
  +                List ptRow = (List)formulaptgs.get(rownum);
  +                List stRow = (List)stringvals.get(rownum);
  +                FormulaRecordAggregate frarecord = (FormulaRecordAggregate)cell;
  +                adjustDoubleList(nmRow, colnum+1);
  +                adjustObjectList(ptRow, colnum+1);
  +                adjustStringList(stRow, colnum+1);
  +                nmRow.set(colnum,frarecord.getFormulaRecord().getValue());
  +                ptRow.set(colnum,frarecord.getFormulaRecord().getParsedExpression());
  +                StringRecord str = frarecord.getStringRecord();
  +                if (str != null) {
  +                    stRow.set(colnum,str.getString());
  +                } else {
  +                    stRow.set(colnum,null);
  +                }
  +                physCells++;
  +                break;
  +            case HSSFCell.CELL_TYPE_BLANK:
  +                //BlankRecord brecord = (BlankRecord)cell;
  +                physCells++;
  +                break;
  +
  +            default:
  +                throw new RuntimeException("UnImplemented Celltype "+cell.toString());
  +        }
  +    }
  +
  +    private int determineType(CellValueRecordInterface cval)
       {
  -        Iterator itr = records.values().iterator();
  -        int      pos = offset;
  +        Record record = ( Record ) cval;
  +        int    sid    = record.getSid();
  +        int    retval = 0;
   
  -        while (itr.hasNext())
  +        switch (sid)
           {
  -            pos += (( Record ) itr.next()).serialize(pos, data);
  +
  +            case NumberRecord.sid :
  +                retval = HSSFCell.CELL_TYPE_NUMERIC;
  +                break;
  +
  +            case BlankRecord.sid :
  +                retval = HSSFCell.CELL_TYPE_BLANK;
  +                break;
  +
  +            case LabelSSTRecord.sid :
  +                retval = HSSFCell.CELL_TYPE_STRING;
  +                break;
  +
  +            case FormulaRecordAggregate.sid :
  +                retval = HSSFCell.CELL_TYPE_FORMULA;
  +                break;
  +
  +            case BoolErrRecord.sid :
  +                BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
  +
  +                retval = (boolErrRecord.isBoolean())
  +                         ? HSSFCell.CELL_TYPE_BOOLEAN
  +                         : HSSFCell.CELL_TYPE_ERROR;
  +                break;
           }
  -        return pos - offset;
  +        return retval;
       }
  -    /**
  -     * called by the constructor, should set class level fields.  Should throw
  -     * runtime exception for bad/icomplete data.
  -     *
  -     * @param data raw data
  -     * @param size size of data
  -     * @param offset of the record's data (provided a big array of the file)
  -     */
   
  -    protected void fillFields(byte [] data, short size, int offset)
  -    {
  +    private void ensureRows(int rownum) {
  +        adjustRows(celltype, rownum+1, IntList.class);
  +        adjustRows(xfs, rownum+1, IntList.class);
  +        adjustRows(numericcells, rownum+1, DoubleList.class);
  +        adjustRows(formulaptgs, rownum+1, ArrayList.class);
  +        adjustRows(stringvals, rownum+1, ArrayList.class);
  +
       }
   
  -    /**
  -     * called by constructor, should throw runtime exception in the event of a
  -     * record passed with a differing ID.
  -     *
  -     * @param id alleged id for this record
  -     */
  +    private void adjustRows(List list, int size, Class theclass) {
  +        while (list.size() < size) {
  +            try {
  +                list.add(theclass.newInstance());
  +            } catch (Exception e) {
  +                throw new RuntimeException("Could Not Instantiate Row in adjustRows");
  +            }
  +        }
  +    }
   
  -    protected void validateSid(short id)
  -    {
  +    private void adjustIntList(IntList list, int size) {
  +        while (list.size() < size) {
  +            list.add(-1);
  +        }
       }
   
  -    /**
  -     * return the non static version of the id for this record.
  -     */
  +    private void adjustDoubleList(DoubleList list, int size) {
  +        while (list.size() < size) {
  +            list.add(-1);
  +        }
  +    }
   
  -    public short getSid()
  -    {
  -        return sid;
  +    private void adjustObjectList(List list, int size) {
  +        while (list.size() < size) {
  +            list.add(new ArrayList());
  +        }
       }
   
  -    public int getRecordSize() {
  -    
  -        int size = 0;
  -        Iterator irecs = records.values().iterator();
  -        
  -        while (irecs.hasNext()) {
  -                size += (( Record ) irecs.next()).getRecordSize();
  +    private void adjustStringList(List list, int size) {
  +        while (list.size() < size) {
  +            list.add(new String());
           }
  +    }
   
  -        return size;
  -//        return size;
  +
  +    protected int findNextPopulatedCell(int row, int col) {
  +
  +        IntList ctRow = (IntList) celltype.get(row);
  +        int retval = -1;
  +        if (ctRow.size() > col+1) {
  +            for (int k = col+1; k < ctRow.size() +1; k++) {
  +
  +                if (k != ctRow.size()) {
  +                   int val = ctRow.get(k);
  +
  +                   if (val != -1) {
  +                       retval = k;
  +                       break;
  +                   }  // end if (val !=...
  +
  +                } //end if (k !=..
  +
  +            }   //end for
  +
  +        }  //end if (ctRow.size()...
  +        return retval;
       }
   
  -    public Iterator getIterator()
  -    {
  -        return records.values().iterator();
  +
  +
  +    public short getSid() {
  +      return sid;
       }
   
  -    /** Performs a deep clone of the record*/
  -    public Object clone() {
  -      ValueRecordsAggregate rec = new ValueRecordsAggregate();
  -      for (Iterator valIter = getIterator(); valIter.hasNext();) {
  -        CellValueRecordInterface val = (CellValueRecordInterface)((CellValueRecordInterface)valIter.next()).clone();
  -        rec.insertCell(val);
  -      }
  -      return rec;
  +
  +    public void fillFields(byte[] data, short size, int offset) {
  +
  +    }
  +
  +    protected void validateSid(short sid) {
  +
       }
  +
  +
   }
   
  -/*
  - * class XYLocator implements Comparable {
  - *   private int row = 0;
  - *   private int col = 0;
  - *   public XYLocator(int row, int col) {
  - *       this.row = row;
  - *       this.col = col;
  - *   }
  - *
  - *   public int getRow() {
  - *       return row;
  - *   }
  - *
  - *   public int getCol() {
  - *       return col;
  - *   }
  - *
  - *   public int compareTo(Object obj) {
  - *        XYLocator loc = (XYLocator)obj;
  - *
  - *        if (this.getRow() == loc.getRow() &&
  - *            this.getCol() == loc.getCol() )
  - *               return 0;
  - *
  - *        if (this.getRow() < loc.getRow())
  - *               return -1;
  - *
  - *        if (this.getRow() > loc.getRow())
  - *               return 1;
  - *
  - *        if (this.getCol() < loc.getCol())
  - *               return -1;
  - *
  - *        if (this.getCol() > loc.getCol())
  - *               return 1;
  - *
  - *        return -1;
  - *
  - *   }
  - *
  - *   public boolean equals(Object obj) {
  - *       if (!(obj instanceof XYLocator)) return false;
  - *
  - *       XYLocator loc = (XYLocator)obj;
  - *       if (this.getRow() == loc.getRow()
  - *             &&
  - *           this.getCol() == loc.getCol()
  - *           ) return true;
  - *      return false;
  - *   }
  - *
  - *
  - * }
  - */
  +class VRAIterator implements Iterator {
  +    private boolean hasNext;
  +    private ValueRecordsAggregate vra;
  +    int popindex;
  +    int row;
  +    int rowlimit;
  +    int col;
  +    CellValueRecordInterface current = null;
  +    CellValueRecordInterface next    = null;
  +
  +    public VRAIterator(ValueRecordsAggregate vra) {
  +        this.vra = vra;
  +        this.rowlimit = -1;
  +        popindex = 0;
  +        if (vra.getPhysicalNumberOfCells() > 0) {
  +            hasNext = true;
  +            next = findNextCell(null);
  +        }
  +    }
  +
  +    public VRAIterator(ValueRecordsAggregate vra, int row) {
  +        this(vra);
  +        rowlimit = row;
  +        this.row = row;
  +        this.popindex = vra.populatedRows.indexOf(row);
  +    }
  +
  +    public boolean hasNext() {
  +        return hasNext;
  +    }
  +
  +    public Object next() {
  +        current = next;
  +        next = findNextCell(current);
  +        if (next == null) {
  +            hasNext = false;
  +        }
  +        return current;
  +    }
  +
  +    public void remove() {
  +       vra.removeCell(current);
  +    }
  +
  +    private CellValueRecordInterface findNextCell(CellValueRecordInterface current) {
  +        IntList ctRow = null;
  +        int rowNum = -1;
  +        int colNum = -1;
  +        int newCol = -1;
  +        boolean wasntFirst = false;
  +
  +        if (current != null) {
  +            wasntFirst = true;
  +            rowNum = current.getRow();
  +            colNum = current.getColumn();
  +            ctRow = ((IntList)vra.celltype.get(rowNum));
  +        }
  +
  +        //if popindex = row iwth no cells, fast forward till we get to one with size > 0
  +        while ((ctRow == null || ctRow.size() == 0) && vra.populatedRows.size() > popindex) {
  +            if (wasntFirst == true) {
  +                throw new RuntimeException("CANT HAPPEN WASNTFIRST BUT WE'RE FASTFORWARDING!");
  +            }
  +            rowNum = vra.populatedRows.get(popindex);
  +            ctRow = (IntList)vra.celltype.get(rowNum);
  +            if (ctRow.size() == 0) {
  +                if (rowlimit == -1) {
  +                    popindex++;
  +                } else {
  +                    this.hasNext = false;
  +                }
  +            }
  +        }
  +
  +        if (rowNum == -1) {
  +            return null;
  +        }
  +
  +        while (newCol == -1) {
  +            newCol = findNextPopulatedCell(rowNum,colNum);
  +            colNum = newCol;
  +            if (colNum == -1) {                          //end of row, forward one row
  +                popindex++;
  +                if (popindex < vra.populatedRows.size() && rowlimit == -1) {
  +                    rowNum = vra.populatedRows.get(popindex);
  +                } else {
  +                    return null;
  +                }
  +            }
  +        }
  +
  +        return vra.constructRecord(rowNum,colNum);
  +    }
  +
  +    private int findNextPopulatedCell(int row, int col) {
  +
  +        /*IntList ctRow = (IntList) vra.celltype.get(row);
  +        int retval = -1;
  +        if (ctRow.size() > col+1) {
  +            for (int k = col+1; k < ctRow.size() +1; k++) {
  +
  +                if (k != ctRow.size()) {
  +                   int val = ctRow.get(k);
  +
  +                   if (val != -1) {
  +                       retval = k;
  +                       break;
  +                   }  // end if (val !=...
  +
  +                } //end if (k !=..
  +
  +            }   //end for
  +
  +        }  //end if (ctRow.size()...
  +        return retval;*/
  +        return vra.findNextPopulatedCell(row, col);
  +    }
  +
  +}
  \ No newline at end of file
  
  
  
  1.4       +8 -4      jakarta-poi/.classpath
  
  Index: .classpath
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/.classpath,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- .classpath	1 Jan 2003 09:24:39 -0000	1.3
  +++ .classpath	19 Jul 2003 02:48:16 -0000	1.4
  @@ -2,9 +2,13 @@
   <classpath>
       <classpathentry kind="src" path="src/testcases"/>
       <classpathentry kind="src" path="src/java"/>
  -    <classpathentry kind="src" path="src/examples/src"/>
  -    <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
  -    <classpathentry kind="lib" path="tools/cents/junit.cent/lib/junit-3.7.jar"/>
  -    <classpathentry kind="lib" path="lib/core/commons-logging-1.0.jar"/>
  +    <classpathentry kind="var" path="JRE_LIB" sourcepath="JRE_SRC"/>
  +    <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/ant.jar"/>
  +    <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/junit.jar"/>
  +    <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/commons-logging.jar"/>
  +    <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/xerces-2.3.0.jar"/>
  +    <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/xercesImpl.jar"/>
  +    <classpathentry kind="lib" path="/Users/andrewoliver/projects/jboss/test/apache-ant-1.5.3-1/lib/xml-apis.jar"/>
  +    <classpathentry kind="lib" path="/Users/andrewoliver/projects/jakarta/poimerge/jakarta-poi/lib/xalan-2.2.0.jar"/>
       <classpathentry kind="output" path="build"/>
   </classpath>
  
  
  
  1.23      +114 -86   jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
  
  Index: HSSFSheet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- HSSFSheet.java	27 Jun 2003 23:57:58 -0000	1.22
  +++ HSSFSheet.java	19 Jul 2003 02:48:16 -0000	1.23
  @@ -62,13 +62,11 @@
   import java.util.ArrayList;
   import java.util.Iterator;
   import java.util.List;
  -import java.util.TreeMap;
   
   import org.apache.poi.hssf.model.Sheet;
   import org.apache.poi.hssf.model.Workbook;
   import org.apache.poi.hssf.record.CellValueRecordInterface;
   import org.apache.poi.hssf.record.HCenterRecord;
  -import org.apache.poi.hssf.record.Record;
   import org.apache.poi.hssf.record.RowRecord;
   import org.apache.poi.hssf.record.SCLRecord;
   import org.apache.poi.hssf.record.VCenterRecord;
  @@ -115,7 +113,9 @@
        */
   
       private Sheet sheet;
  -    private TreeMap rows;
  +   // private TreeMap rows;
  +//    private RowRecordsAggregate rows;
  +//    private ValueRecordsAggregate vra;
       private Workbook book;
       private int firstrow;
       private int lastrow;
  @@ -132,7 +132,7 @@
       protected HSSFSheet(Workbook book)
       {
           sheet = Sheet.createSheet();
  -        rows = new TreeMap();   // new ArrayList(INITIAL_CAPACITY);
  +        //rows = new TreeMap();   // new ArrayList(INITIAL_CAPACITY);
           this.book = book;
       }
   
  @@ -148,7 +148,7 @@
       protected HSSFSheet(Workbook book, Sheet sheet)
       {
           this.sheet = sheet;
  -        rows = new TreeMap();
  +        //rows = new TreeMap();
           this.book = book;
           setPropertiesFromSheet(sheet);
       }
  @@ -164,7 +164,7 @@
   
       private void setPropertiesFromSheet(Sheet sheet)
       {
  -        int sloc = sheet.getLoc();
  +/*        int sloc = sheet.getLoc();
           RowRecord row = sheet.getNextRow();
   
           while (row != null)
  @@ -173,7 +173,9 @@
   
               row = sheet.getNextRow();
           }
  -        sheet.setLoc(sloc);
  +        sheet.setLoc(sloc);*/
  +
  +        /*
           CellValueRecordInterface cval = sheet.getNextValueRecord();
           long timestart = System.currentTimeMillis();
   
  @@ -204,8 +206,9 @@
                   cval = null;
               }
           }
  -        log.log(DEBUG, "total sheet cell creation took ",
  -                new Long(System.currentTimeMillis() - timestart));
  +        */
  +//        log.log(DEBUG, "total sheet cell creation took ",
  +//                new Long(System.currentTimeMillis() - timestart));
       }
   
       /**
  @@ -233,13 +236,13 @@
        * @return HSSFRow high level representation
        */
   
  -    private HSSFRow createRowFromRecord(RowRecord row)
  +/*    private HSSFRow createRowFromRecord(RowRecord row)
       {
           HSSFRow hrow = new HSSFRow(book, sheet, row);
   
           addRow(hrow, false);
           return hrow;
  -    }
  +    }*/
   
       /**
        * Remove a row from this sheet.  All cells contained in the row are removed as well
  @@ -250,35 +253,35 @@
       public void removeRow(HSSFRow row)
       {
           sheet.setLoc(sheet.getDimsLoc());
  -        if (rows.size() > 0)
  -        {
  -            rows.remove(row);
  -            if (row.getRowNum() == getLastRowNum())
  -            {
  -                lastrow = findLastRow(lastrow);
  -            }
  -            if (row.getRowNum() == getFirstRowNum())
  -            {
  -                firstrow = findFirstRow(firstrow);
  -            }
  -            Iterator iter = row.cellIterator();
  +//        if (rows.size() > 0)
  +//        {
  +//            rows.remove(row);
  +        //    if (row.getRowNum() == getLastRowNum())
  +        //    {
  +        //        lastrow = findLastRow(lastrow);
  +         //   }
  +         //   if (row.getRowNum() == getFirstRowNum())
  +         //   {
  +         //       firstrow = findFirstRow(firstrow);
  +         //   }
  +            //Iterator iter = row.cellIterator();
   
  -            while (iter.hasNext())
  +/*            while (iter.hasNext())
               {
                   HSSFCell cell = (HSSFCell) iter.next();
   
                   sheet.removeValueRecord(row.getRowNum(),
                           cell.getCellValueRecord());
  -            }
  +            }*/
               sheet.removeRow(row.getRowRecord());
  -        }
  +        //}
       }
   
       /**
        * used internally to refresh the "last row" when the last row is removed.
        */
   
  -    private int findLastRow(int lastrow)
  +/*    private int findLastRow(int lastrow)
       {
           int rownum = lastrow - 1;
           HSSFRow r = getRow(rownum);
  @@ -288,13 +291,13 @@
               r = getRow(--rownum);
           }
           return rownum;
  -    }
  +    }*/
   
       /**
        * used internally to refresh the "first row" when the first row is removed.
        */
   
  -    private int findFirstRow(int firstrow)
  +    /*private int findFirstRow(int firstrow)
       {
           int rownum = firstrow + 1;
           HSSFRow r = getRow(rownum);
  @@ -308,7 +311,7 @@
               return -1;
   
           return rownum;
  -    }
  +    } */
   
       /**
        * add a row to the sheet
  @@ -318,19 +321,22 @@
   
       private void addRow(HSSFRow row, boolean addLow)
       {
  -        rows.put(row, row);
  -        if (addLow)
  -        {
  -            sheet.addRow(row.getRowRecord());
  +        //rows.put(row, row);
  +        if (addLow) {
  +            RowRecord rec = sheet.getRow(row.getRowNum());
  +            if (rec == null) {
  +                rec = new RowRecord();
  +                sheet.addRow(sheet.createRow(row.getRowNum()));
  +            }
           }
  -        if (row.getRowNum() > getLastRowNum())
  +/*        if (row.getRowNum() > getLastRowNum())
           {
               lastrow = row.getRowNum();
           }
           if (row.getRowNum() < getFirstRowNum())
           {
               firstrow = row.getRowNum();
  -        }
  +        }*/
       }
   
       /**
  @@ -342,11 +348,9 @@
   
       public HSSFRow getRow(int rownum)
       {
  -        HSSFRow row = new HSSFRow();
  +        HSSFRow retval = new HSSFRow(book, sheet, this.sheet.getRow(rownum));
   
  -        //row.setRowNum((short) rownum);
  -        row.setRowNum( rownum);
  -        return (HSSFRow) rows.get(row);
  +        return retval;
       }
   
       /**
  @@ -355,7 +359,7 @@
   
       public int getPhysicalNumberOfRows()
       {
  -        return rows.size();
  +        return sheet.getPhysicalNumberOfRows();
       }
   
       /**
  @@ -365,7 +369,7 @@
   
       public int getFirstRowNum()
       {
  -        return firstrow;
  +        return sheet.getFirstRow();
       }
   
       /**
  @@ -375,7 +379,7 @@
   
       public int getLastRowNum()
       {
  -        return lastrow;
  +        return sheet.getLastRow();
       }
   
       /**
  @@ -592,7 +596,7 @@
   
       public Iterator rowIterator()
       {
  -        return rows.values().iterator();
  +        return new SheetRowIterator(this, this.book);
       }
   
       /**
  @@ -813,66 +817,60 @@
        * @param newPrintGridlines boolean to turn on or off the printing of
        * gridlines
        */
  -    public void setPrintGridlines( boolean newPrintGridlines )
  -    {
  -        getSheet().getPrintGridlines().setPrintGridlines( newPrintGridlines );
  +    public void setPrintGridlines(boolean newPrintGridlines) {
  +        getSheet().getPrintGridlines().setPrintGridlines(newPrintGridlines);
       }
   
       /**
        * Gets the print setup object.
        * @return The user model for the print setup object.
        */
  -    public HSSFPrintSetup getPrintSetup()
  -    {
  -        return new HSSFPrintSetup( getSheet().getPrintSetup() );
  +    public HSSFPrintSetup getPrintSetup() {
  +	return new HSSFPrintSetup(getSheet().getPrintSetup());
       }
   
       /**
        * Gets the user model for the document header.
        * @return The Document header.
        */
  -    public HSSFHeader getHeader()
  -    {
  -        return new HSSFHeader( getSheet().getHeader() );
  +    public HSSFHeader getHeader() {
  +	return new HSSFHeader(getSheet().getHeader());
       }
   
       /**
        * Gets the user model for the document footer.
        * @return The Document footer.
        */
  -    public HSSFFooter getFooter()
  -    {
  -        return new HSSFFooter( getSheet().getFooter() );
  -    }
  +    public HSSFFooter getFooter() {
  +        return new HSSFFooter(getSheet().getFooter());
  +     }
  +
  +     /**
  +      * Sets whether sheet is selected.
  +      * @param sel Whether to select the sheet or deselect the sheet.
  +      */
  +     public void setSelected(boolean sel) {
  +       getSheet().setSelected(sel);
  +     }
  +
  +     /**
  +      * Gets the size of the margin in inches.
  +      * @param margin which margin to get
  +      * @return the size of the margin
  +      */
  +     public double getMargin(short margin) {
  +       return getSheet().getMargin(margin);
  +     }
  +
  +     /**
  +      * Sets the size of the margin in inches.
  +      * @param margin which margin to get
  +      * @param size the size of the margin
  +      */
  +     public void setMargin(short margin, double size) {
  +       getSheet().setMargin(margin, size);
  +      }
   
  -    /**
  -     * Sets whether sheet is selected.
  -     * @param sel Whether to select the sheet or deselect the sheet.
  -     */
  -    public void setSelected( boolean sel )
  -    {
  -        getSheet().setSelected( sel );
  -    }
  -
  -    /**
  -     * Gets the size of the margin in inches.
  -     * @param margin which margin to get
  -     * @return the size of the margin
  -     */
  -    public double getMargin( short margin )
  -    {
  -        return getSheet().getMargin( margin );
  -    }
  -
  -    /**
  -     * Sets the size of the margin in inches.
  -     * @param margin which margin to get
  -     * @param size the size of the margin
  -     */
  -    public void setMargin( short margin, double size )
  -    {
  -        getSheet().setMargin( margin, size );
  -    }
   
       /**
        * Sets the zoom magnication for the sheet.  The zoom is expressed as a
  @@ -903,7 +901,7 @@
   	 * @param endRow
   	 * @param n
   	 * @param isRow
  -	 */
  +	 */ 
   	protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) {
   		List shiftedRegions = new ArrayList();
   		//move merged regions completely if they fall within the new region boundaries when they are shifted
  @@ -1083,6 +1081,36 @@
       public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane )
       {
           getSheet().createSplitPane( xSplitPos, ySplitPos, topRow, leftmostColumn, activePane );
  +    }
  +
  +
  +}
  +
  +class SheetRowIterator implements Iterator {
  +    Iterator rows;
  +    Workbook book;
  +    Sheet sheet;
  +
  +    public SheetRowIterator(HSSFSheet sheet, Workbook book) {
  +        this.sheet = sheet.getSheet();
  +        this.book  = book;
  +        rows = this.sheet.rowRecordIterator();
  +    }
  +
  +    public boolean hasNext() {
  +        return rows.hasNext();
  +    }
  +
  +    public Object next() {
  +        HSSFRow retval = null;
  +        if (rows.hasNext()) {
  +            retval = new HSSFRow(book, sheet, (RowRecord)rows.next());
  +        }
  +        return retval;
  +    }
  +
  +    public void remove() {
  +        rows.remove();
       }
   
   
  
  
  
  1.13      +106 -47   jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java
  
  Index: HSSFRow.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- HSSFRow.java	30 Apr 2003 04:38:59 -0000	1.12
  +++ HSSFRow.java	19 Jul 2003 02:48:16 -0000	1.13
  @@ -63,6 +63,7 @@
   import org.apache.poi.hssf.model.Workbook;
   import org.apache.poi.hssf.record.CellValueRecordInterface;
   import org.apache.poi.hssf.record.RowRecord;
  +import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
   
   import java.util.HashMap;
   import java.util.Iterator;
  @@ -84,7 +85,7 @@
       public final static int INITIAL_CAPACITY = 5;
       //private short rowNum;
       private int rowNum;
  -    private HashMap cells;
  +    //private ValueRecordsAggregate cells;
   //    private short firstcell = -1;
   //    private short lastcell = -1;
   
  @@ -92,7 +93,7 @@
        * reference to low level representation
        */
   
  -    private RowRecord row;
  +    //private RowRecord row;
   
       /**
        * reference to containing low level Workbook
  @@ -123,16 +124,16 @@
       protected HSSFRow(Workbook book, Sheet sheet, int rowNum)
       {
           this.rowNum = rowNum;
  -        cells = new HashMap(10);   // new ArrayList(INITIAL_CAPACITY);
  +        //cells = new HashMap(10);   // new ArrayList(INITIAL_CAPACITY);
           this.book = book;
           this.sheet = sheet;
  -        row = new RowRecord();
  -        row.setHeight((short) 0xff);
  -        row.setLastCol((short) -1);
  -        row.setFirstCol((short) -1);
  +        //row = new RowRecord();
  +        //row.setHeight((short) 0xff);
  +        //row.setLastCol((short) -1);
  +        //row.setFirstCol((short) -1);
   
           // row.setRowNumber(rowNum);
  -        setRowNum(rowNum);
  +        //setRowNum(rowNum);
       }
   
       /**
  @@ -148,10 +149,10 @@
       protected HSSFRow(Workbook book, Sheet sheet, RowRecord record)
       {
           //this.rowNum = rowNum;
  -        cells = new HashMap();   // ArrayList(INITIAL_CAPACITY);
  +        //cells = new HashMap();   // ArrayList(INITIAL_CAPACITY);
           this.book = book;
           this.sheet = sheet;
  -        row = record;
  +        //row = record;
   
           // row.setHeight(record.getHeight());
           // row.setRowNumber(rowNum);
  @@ -175,8 +176,8 @@
       {
           HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column);
   
  -        addCell(cell);
  -        sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
  +        //addCell(cell);
  +        //sheet.addValueRecord(getRowNum(), cell.getCellValueRecord());
           return cell;
       }
   
  @@ -211,15 +212,15 @@
           CellValueRecordInterface cval = cell.getCellValueRecord();
   
           sheet.removeValueRecord(getRowNum(), cval);
  -        cells.remove(new Integer(cell.getCellNum()));
  +        //cells.remove(new Integer(cell.getCellNum()));
   
  -        if (cell.getCellNum() == row.getLastCol())
  +        if (cell.getCellNum() == getLastCol(rowNum))
           {
  -            row.setLastCol(findLastCell(row.getLastCol()));
  +            sheet.getRow(rowNum).setLastCol(findLastCell(sheet.getRow(rowNum).getLastCol()));
           }
  -        if (cell.getCellNum() == row.getFirstCol())
  +        if (cell.getCellNum() == getFirstCol(rowNum))
           {
  -            row.setFirstCol(findFirstCell(row.getFirstCol()));
  +            setFirstCol(findFirstCell(getFirstCol(rowNum)));
           }
       }
   
  @@ -236,7 +237,7 @@
   
           addCell(hcell);
   
  -        // sheet.addValueRecord(getRowNum(),cell.getCellValueRecord());
  +         sheet.addValueRecord(getRowNum(),cell);
           return hcell;
       }
   
  @@ -249,10 +250,10 @@
       public void setRowNum(int rowNum)
       {
           this.rowNum = rowNum;
  -        if (row != null)
  -        {
  -            row.setRowNumber(rowNum);   // used only for KEY comparison (HSSFRow)
  -        }
  +        //if (row != null)
  +        //{
  +        //    row.setRowNumber(rowNum);   // used only for KEY comparison (HSSFRow)
  +        //}
       }
   
       /**
  @@ -272,26 +273,44 @@
   
       private void addCell(HSSFCell cell)
       {
  -        if (row.getFirstCol() == -1)
  +        if (getFirstCol(rowNum) == -1)
           {
  -            row.setFirstCol(cell.getCellNum());
  +            setFirstCol(cell.getCellNum());
           }
  -        if (row.getLastCol() == -1)
  +        if (getLastCol(rowNum) == -1)
           {
  -            row.setLastCol(cell.getCellNum());
  +            setLastCol(cell.getCellNum());
           }
  -        cells.put(new Integer(cell.getCellNum()), cell);
  +        //cells.put(new Integer(cell.getCellNum()), cell);
  +        sheet.addValueRecord(this.rowNum, cell.getCellValueRecord());
   
  -        if (cell.getCellNum() < row.getFirstCol())
  +        if (cell.getCellNum() < getFirstCol(rowNum))
           {
  -            row.setFirstCol(cell.getCellNum());
  +            setFirstCol(cell.getCellNum());
           }
  -        if (cell.getCellNum() > row.getLastCol())
  +        if (cell.getCellNum() > getLastCol(rowNum))
           {
  -            row.setLastCol(cell.getCellNum());
  +            setLastCol(cell.getCellNum());
           }
       }
   
  +    private void setLastCol(short cell) {
  +        sheet.setLastColForRow(rowNum, cell);
  +    }
  +
  +    private void setFirstCol(short cell) {
  +        sheet.setFirstColForRow(rowNum, cell);
  +    }
  +
  +    private short getLastCol(int row) {
  +        return sheet.getLastColForRow(row);
  +    }
  +
  +    private short getFirstCol(int row) {
  +        return sheet.getFirstColForRow(row);
  +    }
  +
  +
       /**
        * get the hssfcell representing a given column (logical cell) 0-based.  If you
        * ask for a cell that is not defined....you get a null.
  @@ -302,6 +321,11 @@
   
       public HSSFCell getCell(short cellnum)
       {
  +        HSSFCell retval = null;
  +        CellValueRecordInterface cval = sheet.getValueRecord(rowNum, cellnum);
  +        if (cval != null) {
  +            retval = new HSSFCell(book, sheet, rowNum, cval);
  +        }
   
   /*        for (int k = 0; k < cells.size(); k++)
           {
  @@ -312,7 +336,7 @@
                   return cell;
               }
           }*/
  -        return (HSSFCell) cells.get(new Integer(cellnum));
  +        return retval;
       }
   
       /**
  @@ -325,7 +349,7 @@
           if (getPhysicalNumberOfCells() == 0)
               return -1;
           else
  -            return row.getFirstCol();
  +            return getFirstCol(rowNum);
       }
   
       /**
  @@ -338,7 +362,7 @@
           if (getPhysicalNumberOfCells() == 0)
               return -1;
           else
  -            return row.getLastCol();
  +            return getLastCol(rowNum);
       }
   
   
  @@ -350,11 +374,13 @@
   
       public int getPhysicalNumberOfCells()
       {
  -        if (cells == null)
  -        {
  -            return 0;   // shouldn't be possible but it is due to missing API support for BLANK/MULBLANK
  -        }
  -        return cells.size();
  +       // sheet.get
  +//        if (cells == null)
  +//        {
  +//            return 0;   // shouldn't be possible but it is due to missing API support for BLANK/MULBLANK
  +//        }
  +//        return cells.size();
  +        return sheet.getPhysicalNumberOfRows();
       }
   
       /**
  @@ -367,8 +393,8 @@
       {
   
           // row.setOptionFlags(
  -        row.setBadFontHeight(true);
  -        row.setHeight(height);
  +        sheet.getRow(rowNum).setBadFontHeight(true);
  +        sheet.getRow(rowNum).setHeight(height);
       }
   
       /**
  @@ -380,8 +406,8 @@
       {
   
           // row.setOptionFlags(
  -        row.setBadFontHeight(true);
  -        row.setHeight((short) (height * 20));
  +        sheet.getRow(rowNum).setBadFontHeight(true);
  +        sheet.getRow(rowNum).setHeight((short) (height * 20));
       }
   
       /**
  @@ -391,7 +417,7 @@
   
       public short getHeight()
       {
  -        return row.getHeight();
  +        return sheet.getRow(rowNum).getHeight();
       }
   
       /**
  @@ -401,7 +427,7 @@
   
       public float getHeightInPoints()
       {
  -        return (row.getHeight() / 20);
  +        return (sheet.getRow(rowNum).getHeight() / 20);
       }
   
       /**
  @@ -413,7 +439,7 @@
   
       protected RowRecord getRowRecord()
       {
  -        return row;
  +        return sheet.getRow(rowNum);
       }
   
       /**
  @@ -457,7 +483,7 @@
   
       public Iterator cellIterator()
       {
  -        return cells.values().iterator();
  +        return new RowCellIterator(this.book,  this.sheet, this.rowNum);
       }
   
       public int compareTo(Object obj)
  @@ -494,3 +520,36 @@
           return false;
       }
   }
  +
  +
  +class RowCellIterator implements Iterator {
  +    Iterator cells;
  +    Workbook book;
  +    Sheet sheet;
  +    int row;
  +
  +    public RowCellIterator(Workbook book, Sheet sheet, int row) {
  +        this.sheet = sheet;
  +        this.book  = book;
  +        this.row = row;
  +        cells = this.sheet.rowCellIterator(row);
  +    }
  +
  +    public boolean hasNext() {
  +        return cells.hasNext();
  +    }
  +
  +    public Object next() {
  +        HSSFCell retval = null;
  +        if (cells.hasNext()) {
  +            retval = new HSSFCell(book, sheet, row, ((CellValueRecordInterface)cells.next()));
  +        }
  +        return retval;
  +    }
  +
  +    public void remove() {
  +        cells.remove();
  +    }
  +
  +
  +}
  \ No newline at end of file
  
  
  
  1.25      +11 -18    jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
  
  Index: HSSFWorkbook.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- HSSFWorkbook.java	30 Apr 2003 04:39:00 -0000	1.24
  +++ HSSFWorkbook.java	19 Jul 2003 02:48:16 -0000	1.25
  @@ -59,26 +59,11 @@
    */
   package org.apache.poi.hssf.usermodel;
   
  -import java.io.ByteArrayInputStream;
  -import java.io.IOException;
  -import java.io.InputStream;
  -import java.io.OutputStream;
  -import java.util.ArrayList;
  -import java.util.Iterator;
  -import java.util.List;
  -import java.util.Stack;
  -
  +import org.apache.poi.util.POILogFactory;
   import org.apache.poi.hssf.eventmodel.EventRecordFactory;
   import org.apache.poi.hssf.model.Sheet;
   import org.apache.poi.hssf.model.Workbook;
  -import org.apache.poi.hssf.record.BackupRecord;
  -import org.apache.poi.hssf.record.ExtendedFormatRecord;
  -import org.apache.poi.hssf.record.FontRecord;
  -import org.apache.poi.hssf.record.NameRecord;
  -import org.apache.poi.hssf.record.RecordFactory;
  -import org.apache.poi.hssf.record.SSTRecord;
  -import org.apache.poi.hssf.record.UnknownRecord;
  -import org.apache.poi.hssf.record.WindowTwoRecord;
  +import org.apache.poi.hssf.record.*;
   import org.apache.poi.hssf.record.formula.Area3DPtg;
   import org.apache.poi.hssf.record.formula.MemFuncPtg;
   import org.apache.poi.hssf.record.formula.UnionPtg;
  @@ -88,8 +73,16 @@
   import org.apache.poi.poifs.filesystem.DocumentInputStream;
   import org.apache.poi.poifs.filesystem.Entry;
   import org.apache.poi.poifs.filesystem.POIFSFileSystem;
  -import org.apache.poi.util.POILogFactory;
   import org.apache.poi.util.POILogger;
  +
  +import java.io.ByteArrayInputStream;
  +import java.io.IOException;
  +import java.io.InputStream;
  +import java.io.OutputStream;
  +import java.util.ArrayList;
  +import java.util.Iterator;
  +import java.util.List;
  +import java.util.Stack;
   
   /**
    * High level representation of a workbook.  This is the first object most users
  
  
  
  1.23      +64 -38    jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
  
  Index: HSSFCell.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- HSSFCell.java	30 Apr 2003 04:39:00 -0000	1.22
  +++ HSSFCell.java	19 Jul 2003 02:48:16 -0000	1.23
  @@ -163,7 +163,7 @@
       private Sheet                    sheet;
       //private short                    row;
       private int                    row;
  -    private CellValueRecordInterface record;
  +//    private CellValueRecordInterface record;
   
       /**
        * Creates new Cell - Should only be called by HSSFRow.  This creates a cell
  @@ -196,13 +196,25 @@
           this.book    = book;
           this.sheet   = sheet;
   
  +        BlankRecord rec = new BlankRecord();
  +        rec.setRow(row);
  +        rec.setColumn(cellNum);
  +
  +        rec.setXFIndex((short)0xf);
  +
  +        cellType = HSSFCell.CELL_TYPE_BLANK;
  +        sheet.addValueRecord(row,(CellValueRecordInterface)rec);
  +
  +
  +
           // Relying on the fact that by default the cellType is set to 0 which
           // is different to CELL_TYPE_BLANK hence the following method call correctly
           // creates a new blank cell.
  -        setCellType(CELL_TYPE_BLANK, false);
  -        ExtendedFormatRecord xf = book.getExFormatAt(0xf);
  +        //setCellType(CELL_TYPE_BLANK, false);
  +
  +        //ExtendedFormatRecord xf = book.getExFormatAt(0xf);
  +        //setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
   
  -        setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
       }
   
       /**
  @@ -236,7 +248,7 @@
           errorValue   = ( byte ) 0;
           this.book    = book;
           this.sheet   = sheet;
  -        switch (type)
  +/*        switch (type)
           {
   
               case CELL_TYPE_NUMERIC :
  @@ -285,7 +297,7 @@
           }
           ExtendedFormatRecord xf = book.getExFormatAt(0xf);
   
  -        setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
  +        setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));   */
       }
   
       /**
  @@ -302,7 +314,7 @@
                          CellValueRecordInterface cval)
       {
           cellNum     = cval.getColumn();
  -        record      = cval;
  +        //record      = cval;
           this.row    = row;
           cellType    = determineType(cval);
           cellStyle   = null;
  @@ -394,8 +406,14 @@
   
       public void setCellNum(short num)
       {
  +        CellValueRecordInterface cval = sheet.getValueRecord(row, cellNum);
  +        if (cval != null) {
  +            sheet.removeValueRecord(this.row, cval);
  +        }
           cellNum = num;
  -        record.setColumn(num);
  +        sheet.addValueRecord(row, cval);
  +        //record.setColumn(num);
  +
       }
   
       /**
  @@ -457,16 +475,16 @@
                   }
                   else
                   {
  -                    frec = ( FormulaRecordAggregate ) record;
  +                    frec = (FormulaRecordAggregate)sheet.getValueRecord(row, cellNum);
                   }
                   frec.setColumn(getCellNum());
                   if (setValue)
                   {
                       frec.getFormulaRecord().setValue(getNumericCellValue());
                   }
  -                frec.setXFIndex(( short ) cellStyle.getIndex());
  +//                frec.setXFIndex(( short ) cellStyle.getIndex());
                   frec.setRow(row);
  -                record = frec;
  +                sheet.replaceValueRecord(frec);
                   break;
   
               case CELL_TYPE_NUMERIC :
  @@ -478,16 +496,16 @@
                   }
                   else
                   {
  -                    nrec = ( NumberRecord ) record;
  +                    nrec = ( NumberRecord ) sheet.getValueRecord(row, cellNum);
                   }
                   nrec.setColumn(getCellNum());
                   if (setValue)
                   {
                       nrec.setValue(getNumericCellValue());
                   }
  -                nrec.setXFIndex(( short ) cellStyle.getIndex());
  +                nrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
                   nrec.setRow(row);
  -                record = nrec;
  +                sheet.replaceValueRecord(nrec);
                   break;
   
               case CELL_TYPE_STRING :
  @@ -499,11 +517,11 @@
                   }
                   else
                   {
  -                    lrec = ( LabelSSTRecord ) record;
  +                    lrec = ( LabelSSTRecord ) sheet.getValueRecord(row, cellNum);
                   }
                   lrec.setColumn(getCellNum());
                   lrec.setRow(row);
  -                lrec.setXFIndex(( short ) cellStyle.getIndex());
  +                lrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
                   if (setValue)
                   {
                       if ((getStringCellValue() != null)
  @@ -523,7 +541,7 @@
                           lrec.setSSTIndex(sst);
                       }
                   }
  -                record = lrec;
  +                sheet.replaceValueRecord(lrec);
                   break;
   
               case CELL_TYPE_BLANK :
  @@ -535,21 +553,21 @@
                   }
                   else
                   {
  -                    brec = ( BlankRecord ) record;
  +                    brec = ( BlankRecord ) sheet.getValueRecord(row, cellNum);
                   }
                   brec.setColumn(getCellNum());
   
                   // During construction the cellStyle may be null for a Blank cell.
                   if (cellStyle != null)
                   {
  -                    brec.setXFIndex(( short ) cellStyle.getIndex());
  +                    brec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
                   }
                   else
                   {
                       brec.setXFIndex(( short ) 0);
                   }
                   brec.setRow(row);
  -                record = brec;
  +                sheet.replaceValueRecord(brec);
                   break;
   
               case CELL_TYPE_BOOLEAN :
  @@ -561,7 +579,7 @@
                   }
                   else
                   {
  -                    boolRec = ( BoolErrRecord ) record;
  +                    boolRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum);
                   }
                   boolRec.setColumn(getCellNum());
                   if (setValue)
  @@ -570,7 +588,7 @@
                   }
                   boolRec.setXFIndex(( short ) cellStyle.getIndex());
                   boolRec.setRow(row);
  -                record = boolRec;
  +                sheet.replaceValueRecord(boolRec);
                   break;
   
               case CELL_TYPE_ERROR :
  @@ -582,7 +600,7 @@
                   }
                   else
                   {
  -                    errRec = ( BoolErrRecord ) record;
  +                    errRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum);
                   }
                   errRec.setColumn(getCellNum());
                   if (setValue)
  @@ -591,16 +609,17 @@
                   }
                   errRec.setXFIndex(( short ) cellStyle.getIndex());
                   errRec.setRow(row);
  -                record = errRec;
  +                sheet.replaceValueRecord(errRec);
                   break;
           }
           if (cellType != this.cellType)
           {
               int loc = sheet.getLoc();
   
  -            sheet.replaceValueRecord(record);
  +            //sheet.replaceValueRecord(record);
               sheet.setLoc(loc);
           }
  +        //sheet.setCellType(this.row, this.cellNum);
           this.cellType = cellType;
       }
   
  @@ -631,7 +650,7 @@
           {
               setCellType(CELL_TYPE_NUMERIC, false);
           }
  -        (( NumberRecord ) record).setValue(value);
  +        sheet.setCellValue(row, cellNum, value);
           cellValue = value;
       }
   
  @@ -693,7 +712,7 @@
               {
                   index = book.addSSTString(value, true);
               }
  -            (( LabelSSTRecord ) record).setSSTIndex(index);
  +            sheet.setCellValue(row, cellNum, index);
               stringValue = value;
           }
       }
  @@ -704,12 +723,12 @@
               setCellType(CELL_TYPE_BLANK,false);
           } else {
               setCellType(CELL_TYPE_FORMULA,false);
  -            FormulaRecordAggregate rec = (FormulaRecordAggregate) record;
  +            FormulaRecordAggregate rec = new FormulaRecordAggregate(new FormulaRecord(), null);
               rec.getFormulaRecord().setOptions(( short ) 2);
               rec.getFormulaRecord().setValue(0);
  -            
  -            //only set to default if there is no extended format index already set
  -            if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f);
  +            rec.setRow(row);
  +            rec.setColumn(cellNum);
  +            rec.setXFIndex(( short ) 0x0f);
               FormulaParser fp = new FormulaParser(formula+";",book);
               fp.parse();
               Ptg[] ptg  = fp.getRPNPtg();
  @@ -720,6 +739,9 @@
                   rec.getFormulaRecord().pushExpressionToken(ptg[ k ]);
               }
               rec.getFormulaRecord().setExpressionLength(( short ) size);
  +
  +            sheet.replaceValueRecord(rec);
  +            //sheet.setCellFormula(row, cellNum, options, value
               //Workbook.currentBook = null;
           }
       }
  @@ -727,7 +749,8 @@
       public String getCellFormula() {
           //Workbook.currentBook=book;
           SheetReferences refs = book.getSheetReferences();
  -        String retval = FormulaParser.toFormulaString(refs, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
  +        String retval = FormulaParser.toFormulaString(refs,
  +                ((FormulaRecordAggregate)sheet.getValueRecord(row,cellNum)).getFormulaRecord().getParsedExpression());
           //Workbook.currentBook=null;
           return retval;
       }
  @@ -834,12 +857,12 @@
   
       public void setCellValue(boolean value)
       {
  -        if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA))
  +        /*if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA))
           {
               setCellType(CELL_TYPE_BOOLEAN, false);
           }
           (( BoolErrRecord ) record).setValue(value);
  -        booleanValue = value;
  +        booleanValue = value;                      */
       }
   
       /**
  @@ -853,11 +876,11 @@
   
       public void setCellErrorValue(byte value)
       {
  -        if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
  +        /*if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
           {
               setCellType(CELL_TYPE_ERROR, false);
           }
  -        (( BoolErrRecord ) record).setValue(value);
  +        (( BoolErrRecord ) record).setValue(value);*/
           errorValue = value;
       }
   
  @@ -911,7 +934,8 @@
       public void setCellStyle(HSSFCellStyle style)
       {
           cellStyle = style;
  -        record.setXFIndex(style.getIndex());
  +
  +        sheet.setCellStyle(row, cellNum, style.getIndex());
       }
   
       /**
  @@ -961,7 +985,7 @@
   
       protected CellValueRecordInterface getCellValueRecord()
       {
  -        return record;
  +        return sheet.getValueRecord(row, cellNum);
       }
   
       /**
  @@ -976,6 +1000,7 @@
             throw new RuntimeException("You cannot reference columns with an index of less then 0.");
         }
       }
  +
       
       /**
        * Sets this cell as the active cell for the worksheet
  @@ -985,4 +1010,5 @@
           this.sheet.setActiveCellRow(this.row);
           this.sheet.setActiveCellCol(this.cellNum);
       }
  +
   }
  
  
  
  1.36      +68 -11    jakarta-poi/src/java/org/apache/poi/hssf/model/Sheet.java
  
  Index: Sheet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/model/Sheet.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- Sheet.java	9 Jul 2003 20:20:22 -0000	1.35
  +++ Sheet.java	19 Jul 2003 02:48:17 -0000	1.36
  @@ -234,16 +234,18 @@
               }
               else if ( rec.getSid() == RowRecord.sid )
               {
  -            	 RowRecord row = (RowRecord)rec;
  -            	 if (!isfirstrow) rec = null; //only add the aggregate once
  -            	 
                   if ( isfirstrow )
                   {
                       retval.rows = new RowRecordsAggregate();
  -                    rec = retval.rows;                    
  +                    rec = retval.rows;
  +                    retval.rows.construct( k, recs );
                       isfirstrow = false;
                   }
  -                retval.rows.insertRow(row);
  +                else
  +                {
  +                    rec = null;
  +                }
  +
               }
               else if ( rec.getSid() == PrintGridlinesRecord.sid )
               {
  @@ -261,10 +263,6 @@
               {
                   retval.printSetup = (PrintSetupRecord) rec;
               }
  -            else if ( rec.getSid() == SelectionRecord.sid )
  -            {
  -                retval.selection = (SelectionRecord) rec;
  -            }
   
               if (rec != null)
               {
  @@ -527,6 +525,11 @@
           return numMergedRegions;
       }
   
  +    public CellValueRecordInterface getValueRecord (int row, short col) {
  +       return cells.getCell(row, col);
  +    }
  +
  +
       /**
        * This is basically a kludge to deal with the now obsolete Label records.  If
        * you have to read in a sheet that contains Label records, be aware that the rest
  @@ -1134,6 +1137,7 @@
   
           setLoc(getDimsLoc());
           rows.removeRow(row);
  +        cells.removeRow(row.getRowNumber());
   
           /*
            * for (int k = loc; k < records.size(); k++)
  @@ -1310,6 +1314,9 @@
       public RowRecord getRow(int rownum)
       {
           log.log(log.DEBUG, "getNextRow loc= " + loc);
  +        if (rows == null) {
  +            return null;
  +        }
           return rows.getRow(rownum);
   
           /*
  @@ -1334,6 +1341,15 @@
           // return null;
       }
   
  +
  +    public Iterator rowRecordIterator() {
  +        return rows.getIterator();
  +    }
  +
  +    public Iterator rowCellIterator(int row) {
  +        return this.cells.getRowCellIterator(row);
  +    }
  +
       /**
        * Not currently used method to calculate and add dbcell records
        *
  @@ -1412,6 +1428,15 @@
           }
       }
   
  +    public int getFirstRow() {
  +        return rows.getFirstRowNum();
  +    }
  +
  +    public int getLastRow() {
  +        return rows.getLastRowNum();
  +    }
  +
  +
       /** not currently used */
   
       private DBCellRecord createDBCell(int offset, IntList rowoffsets,
  @@ -1868,7 +1893,7 @@
               for (k = 0; k < columnSizes.size(); k++)
               {
                   ci = ( ColumnInfoRecord ) columnSizes.get(k);
  -                if ((ci.getFirstColumn() <= column)
  +                if ((ci.getFirstColumn() >= column)
                           && (column <= ci.getLastColumn()))
                   {
                       break;
  @@ -1907,7 +1932,7 @@
           for (k = 0; k < columnSizes.size(); k++)
           {
               ci = ( ColumnInfoRecord ) columnSizes.get(k);
  -            if ((ci.getFirstColumn() <= column)
  +            if ((ci.getFirstColumn() >= column)
                       && (column <= ci.getLastColumn()))
               {
                   break;
  @@ -2136,6 +2161,32 @@
           return new EOFRecord();
       }
   
  +    public void setLastColForRow(int row, short col) {
  +        this.getRow(row).setLastCol(col);
  +    }
  +
  +    public void setFirstColForRow(int row, short col) {
  +        this.getRow(row).setFirstCol(col);
  +    }
  +
  +    public short getLastColForRow(int row) {
  +        return this.getRow(row).getLastCol();
  +    }
  +
  +
  +    public short getFirstColForRow(int row) {
  +        return this.getRow(row).getFirstCol();
  +    }
  +
  +    public void setCellValue(int row, short col, double val) {
  +        this.cells.setValue(row, col, val);
  +    }  
  +
  +    public void setCellStyle(int row, short col, short xf) {
  +        this.cells.setStyle(row, col, xf);
  +    }
  +
  +
       /**
        * get the location of the DimensionsRecord (which is the last record before the value section)
        * @return location in the array of records of the DimensionsRecord
  @@ -2168,6 +2219,7 @@
           {
               retval += (( Record ) records.get(k)).getRecordSize();
           }
  +
           return retval;
       }
   
  @@ -2202,6 +2254,11 @@
           }
           return null;
       }
  +
  +    public int getPhysicalNumberOfRows() {
  +        return rows.getPhysicalNumberOfRows();
  +    }
  +
   
       /**
        * Sets the SCL record or creates it in the correct place if it does not
  
  
  
  1.22      +8 -0      jakarta-poi/src/java/org/apache/poi/hssf/record/FormulaRecord.java
  
  Index: FormulaRecord.java
  ===================================================================
  RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/FormulaRecord.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- FormulaRecord.java	2 Jun 2003 02:47:44 -0000	1.21
  +++ FormulaRecord.java	19 Jul 2003 02:48:17 -0000	1.22
  @@ -343,6 +343,14 @@
       }
   
       /**
  +     * sets the stack with a list
  +     */
  +    public void setParsedExpression(List ptgs) {
  +        field_8_parsed_expr = new Stack();
  +        field_8_parsed_expr.addAll(ptgs);
  +    }
  +
  +    /**
        * called by constructor, should throw runtime exception in the event of a
        * record passed with a differing ID.
        *