FileDocCategorySizeDatePackage
RowRecordsAggregate.javaAPI DocApache Poi 3.0.114504Thu May 31 18:44:06 BST 2007org.apache.poi.hssf.record.aggregates

RowRecordsAggregate

public class RowRecordsAggregate extends Record
author
andy
author
Jason Height (jheight at chariot dot net dot au)

Fields Summary
int
firstrow
int
lastrow
Map
records
int
size
Constructors Summary
public RowRecordsAggregate()
Creates a new instance of ValueRecordsAggregate


           

     
    
        records = new TreeMap();
    
Methods Summary
public java.lang.Objectclone()
Performs a deep clone of the record

        RowRecordsAggregate rec = new RowRecordsAggregate();
        for ( Iterator rowIter = getIterator(); rowIter.hasNext(); )
        {
            //return the cloned Row Record & insert
            RowRecord row = (RowRecord) ( (RowRecord) rowIter.next() ).clone();
            rec.insertRow( row );
        }
        return rec;
    
public voidcollapseRow(int rowNumber)


        // Find the start of the group.
        int startRow = findStartOfRowOutlineGroup( rowNumber );
        RowRecord rowRecord = (RowRecord) getRow( startRow );

        // Hide all the columns until the end of the group
        int lastRow = writeHidden( rowRecord, startRow, true );

        // Write collapse field
        if (getRow(lastRow + 1) != null)
        {
            getRow(lastRow + 1).setColapsed( true );
        }
        else
        {
            RowRecord row = createRow( lastRow + 1);
            row.setColapsed( true );
            insertRow( row );
        }
    
public static org.apache.poi.hssf.record.RowRecordcreateRow(int row)
Create a row record.

param
row number
return
RowRecord created for the passed in row number
see
org.apache.poi.hssf.record.RowRecord

        RowRecord rowrec = new RowRecord();

        //rowrec.setRowNumber(( short ) row);
        rowrec.setRowNumber(row);
        rowrec.setHeight(( short ) 0xff);
        rowrec.setOptimize(( short ) 0x0);
        rowrec.setOptionFlags(( short ) 0x100);  // seems necessary for outlining
        rowrec.setXFIndex(( short ) 0xf);
        return rowrec;
    
public voidexpandRow(int rowNumber)

        int idx = rowNumber;
        if (idx == -1)
            return;

        // If it is already expanded do nothing.
        if (!isRowGroupCollapsed(idx))
            return;

        // Find the start of the group.
        int startIdx = findStartOfRowOutlineGroup( idx );
        RowRecord row = getRow( startIdx );

        // Find the end of the group.
        int endIdx = findEndOfRowOutlineGroup( idx );

        // expand:
        // colapsed bit must be unset
        // hidden bit gets unset _if_ surrounding groups are expanded you can determine
        //   this by looking at the hidden bit of the enclosing group.  You will have
        //   to look at the start and the end of the current group to determine which
        //   is the enclosing group
        // hidden bit only is altered for this outline level.  ie.  don't uncollapse contained groups
        if ( !isRowGroupHiddenByParent( idx ) )
        {
            for ( int i = startIdx; i <= endIdx; i++ )
            {
                if ( row.getOutlineLevel() == getRow( i ).getOutlineLevel() )
                    getRow( i ).setZeroHeight( false );
                else if (!isRowGroupCollapsed(i))
                    getRow( i ).setZeroHeight( false );
            }
        }

        // Write collapse field
        getRow( endIdx + 1 ).setColapsed( false );
    
protected voidfillFields(org.apache.poi.hssf.record.RecordInputStream in)
called by the constructor, should set class level fields. Should throw runtime exception for bad/incomplete data.

param
data raw data
param
size size of data
param
offset of the record's data (provided a big array of the file)

    
public intfindEndOfRowOutlineGroup(int row)

        int level = getRow( row ).getOutlineLevel();
        int currentRow;
        for (currentRow = row; currentRow < this.getLastRowNum(); currentRow++)
        {
            if (getRow(currentRow) == null || getRow(currentRow).getOutlineLevel() < level)
            {
                break;
            }
        }

        return currentRow-1;
    
public intfindStartOfRowOutlineGroup(int row)

        // Find the start of the group.
        RowRecord rowRecord = this.getRow( row );
        int level = rowRecord.getOutlineLevel();
        int currentRow = row;
        while (this.getRow( currentRow ) != null)
        {
            rowRecord = this.getRow( currentRow );
            if (rowRecord.getOutlineLevel() < level)
                return currentRow + 1;
            currentRow--;
        }

        return currentRow + 1;
    
public intgetEndRowNumberForBlock(int block)
Returns the physical row number of the end row in a block

      int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1;
      if (endIndex >= records.size())
        endIndex = records.size()-1;

      Iterator rowIter = records.values().iterator();
      RowRecord row = null;
      for (int i=0; i<=endIndex;i++) {
        row = (RowRecord)rowIter.next();
      }
      return row.getRowNumber();
    
public intgetFirstRowNum()

        return firstrow;
    
public java.util.IteratorgetIterator()

        return records.values().iterator();
    
public intgetLastRowNum()

        return lastrow;
    
public intgetPhysicalNumberOfRows()

        return records.size();
    
public intgetRecordSize()

        return size;
    
public org.apache.poi.hssf.record.RowRecordgetRow(int rownum)


        // Integer integer = new Integer(rownum);
        RowRecord row = new RowRecord();

        row.setRowNumber(( short ) rownum);
        return ( RowRecord ) records.get(row);
    
public intgetRowBlockCount()
Returns the number of row blocks.

The row blocks are goupings of rows that contain the DBCell record after them

      int size = records.size()/DBCellRecord.BLOCK_SIZE;
      if ((records.size() % DBCellRecord.BLOCK_SIZE) != 0)
          size++;
      return size;
    
public intgetRowBlockSize(int block)

      return 20 * getRowCountForBlock(block);
    
public intgetRowCountForBlock(int block)
Returns the number of physical rows within a block

      int startIndex = block * DBCellRecord.BLOCK_SIZE;
      int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1;
      if (endIndex >= records.size())
        endIndex = records.size()-1;

      return endIndex-startIndex+1;
    
public shortgetSid()
return the non static version of the id for this record.

        return -1000;
    
public intgetStartRowNumberForBlock(int block)
Returns the physical row number of the first row in a block

      //Given that we basically iterate through the rows in order,
      //For a performance improvement, it would be better to return an instance of
      //an iterator and use that instance throughout, rather than recreating one and
      //having to move it to the right position.
      int startIndex = block * DBCellRecord.BLOCK_SIZE;
      Iterator rowIter = records.values().iterator();
      RowRecord row = null;
      //Position the iterator at the start of the block
      for (int i=0; i<=startIndex;i++) {
        row = (RowRecord)rowIter.next();
      }

      return row.getRowNumber();
    
public voidinsertRow(org.apache.poi.hssf.record.RowRecord row)

        size += row.getRecordSize();

        // Integer integer = new Integer(row.getRowNumber());
        records.put(row, row);
        if ((row.getRowNumber() < firstrow) || (firstrow == -1))
        {
            firstrow = row.getRowNumber();
        }
        if ((row.getRowNumber() > lastrow) || (lastrow == -1))
        {
            lastrow = row.getRowNumber();
        }
    
public booleanisRowGroupCollapsed(int row)

        int collapseRow = findEndOfRowOutlineGroup( row ) + 1;

        if (getRow(collapseRow) == null)
            return false;
        else
            return getRow( collapseRow ).getColapsed();
    
public booleanisRowGroupHiddenByParent(int row)

        // Look out outline details of end
        int endLevel;
        boolean endHidden;
        int endOfOutlineGroupIdx = findEndOfRowOutlineGroup( row );
        if (getRow( endOfOutlineGroupIdx + 1 ) == null)
        {
            endLevel = 0;
            endHidden = false;
        }
        else
        {
            endLevel = getRow( endOfOutlineGroupIdx + 1).getOutlineLevel();
            endHidden = getRow( endOfOutlineGroupIdx + 1).getZeroHeight();
        }

        // Look out outline details of start
        int startLevel;
        boolean startHidden;
        int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row );
        if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null)
        {
            startLevel = 0;
            startHidden = false;
        }
        else
        {
            startLevel = getRow( startOfOutlineGroupIdx - 1).getOutlineLevel();
            startHidden = getRow( startOfOutlineGroupIdx - 1 ).getZeroHeight();
        }

        if (endLevel > startLevel)
        {
            return endHidden;
        }
        else
        {
            return startHidden;
        }
    
public voidremoveRow(org.apache.poi.hssf.record.RowRecord row)

        size -= row.getRecordSize();

        // Integer integer = new Integer(row.getRowNumber());
        records.remove(row);
    
public intserialize(int offset, byte[] data)

      throw new RuntimeException("The serialize method that passes in cells should be used");
    
public intserialize(int offset, byte[] data, org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate cells)
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 offset to begin writing at
param
data byte array containing instance data
return
number of bytes written

        int pos = offset;

        //DBCells are serialized before row records.
        final int blockCount = getRowBlockCount();
        for (int block=0;block<blockCount;block++) {
          //Serialize a block of rows.
          //Hold onto the position of the first row in the block
          final int rowStartPos = pos;
          //Hold onto the size of this block that was serialized
          final int rowBlockSize = serializeRowBlock(block, pos, data);
          pos += rowBlockSize;
          //Serialize a block of cells for those rows
          final int startRowNumber = getStartRowNumberForBlock(block);
          final int endRowNumber = getEndRowNumberForBlock(block);
          DBCellRecord cellRecord = new DBCellRecord();
          //Note: Cell references start from the second row...
          int cellRefOffset = (rowBlockSize-20);
          for (int row=startRowNumber;row<=endRowNumber;row++) {
            if (null != cells && cells.rowHasCells(row)) {
              final int rowCellSize = cells.serializeCellRow(row, pos, data);
              pos += rowCellSize;
              //Add the offset to the first cell for the row into the DBCellRecord.
              cellRecord.addCellOffset((short)cellRefOffset);
              cellRefOffset = rowCellSize;
            }
          }
          //Calculate Offset from the start of a DBCellRecord to the first Row
          cellRecord.setRowOffset(pos - rowStartPos);
          pos += cellRecord.serialize(pos, data);

        }
        return pos - offset;
    
private intserializeRowBlock(int block, int offset, byte[] data)
Serializes a block of the rows

      final int startIndex = block*DBCellRecord.BLOCK_SIZE;
      final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE;

      Iterator rowIterator = records.values().iterator();
      int pos = offset;

      //Given that we basically iterate through the rows in order,
      //For a performance improvement, it would be better to return an instance of
      //an iterator and use that instance throughout, rather than recreating one and
      //having to move it to the right position.
      int i=0;
      for (;i<startIndex;i++)
        rowIterator.next();
      while(rowIterator.hasNext() && (i++ < endIndex)) {
        RowRecord row = (RowRecord)rowIterator.next();
        pos += row.serialize(pos, data);
      }
      return pos - offset;
    
protected voidvalidateSid(short id)
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

    
public intwriteHidden(org.apache.poi.hssf.record.RowRecord rowRecord, int row, boolean hidden)

        int level = rowRecord.getOutlineLevel();
        while (rowRecord != null && this.getRow(row).getOutlineLevel() >= level)
        {
            rowRecord.setZeroHeight( hidden );
            row++;
            rowRecord = this.getRow( row );
        }
        return row - 1;