]> source.dussan.org Git - poi.git/commitdiff
Bugzilla 46776 - Added clone() method to MulBlankRecord to fix crash in Sheet.cloneSh...
authorJosh Micich <josh@apache.org>
Sat, 6 Jun 2009 00:46:41 +0000 (00:46 +0000)
committerJosh Micich <josh@apache.org>
Sat, 6 Jun 2009 00:46:41 +0000 (00:46 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@782177 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/MulBlankRecord.java
src/testcases/org/apache/poi/hssf/model/TestSheet.java

index 99942aaaeba75184e1dbf0512efda485d7db55c5..6ba397d18249de02814fc25d4b9707e9052ac850 100644 (file)
@@ -35,6 +35,7 @@
         <release version="3.5-beta7" date="2009-??-??">
         </release>
         <release version="3.5-beta6" date="2009-06-11">
+           <action dev="POI-DEVELOPERS" type="fix">46776 - Added clone() method to MulBlankRecord to fix crash in Sheet.cloneSheet()</action>
            <action dev="POI-DEVELOPERS" type="fix">47244 - Fixed HSSFSheet to handle missing header / footer records</action>
            <action dev="POI-DEVELOPERS" type="fix">47312 - Fixed formula parser to properly reject cell references with a '0' row component</action>
            <action dev="POI-DEVELOPERS" type="fix">47199 - Fixed PageSettingsBlock/Sheet to tolerate margin records after other non-PSB records</action>
index 20a061a026e41eaf6947e3fd8b6b8801be0b1333..87d4eafeacca6f94c08bf087378923576d1a01b6 100644 (file)
@@ -22,128 +22,114 @@ import org.apache.poi.util.LittleEndianOutput;
 /**
  * Title:        Multiple Blank cell record(0x00BE) <P/>
  * Description:  Represents a  set of columns in a row with no value but with styling.
- *               In this release we have read-only support for this record type.
- *               The RecordFactory converts this to a set of BlankRecord objects.<P/>
+ * <p/>
  * REFERENCE:  PG 329 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P/>
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @author Glen Stampoultzis (glens at apache.org)
  * @see BlankRecord
  */
 public final class MulBlankRecord extends StandardRecord {
-    public final static short sid = 0x00BE;
-    
-    private int               field_1_row;
-    private short             field_2_first_col;
-    private short[]           field_3_xfs;
-    private short             field_4_last_col;
-
-    public MulBlankRecord(int row, int firstCol, short[] xfs) {
-        field_1_row = row;
-        field_2_first_col = (short)firstCol;
-        field_3_xfs = xfs;
-        field_4_last_col = (short) (firstCol + xfs.length - 1);
-    }
-
-    /**
-     * get the row number of the cells this represents
-     *
-     * @return row number
-     */
-    public int getRow()
-    {
-        return field_1_row;
-    }
-
-    /**
-     * starting column (first cell this holds in the row)
-     * @return first column number
-     */
-    public short getFirstColumn()
-    {
-        return field_2_first_col;
-    }
-
-    /**
-     * ending column (last cell this holds in the row)
-     * @return first column number
-     */
-    public short getLastColumn()
-    {
-        return field_4_last_col;
-    }
-
-    /**
-     * get the number of columns this contains (last-first +1)
-     * @return number of columns (last - first +1)
-     */
-    public int getNumColumns()
-    {
-        return field_4_last_col - field_2_first_col + 1;
-    }
-
-    /**
-     * returns the xf index for column (coffset = column - field_2_first_col)
-     * @param coffset  the column (coffset = column - field_2_first_col)
-     * @return the XF index for the column
-     */
-    public short getXFAt(int coffset)
-    {
-        return field_3_xfs[ coffset ];
-    }
-
-    /**
-     * @param in the RecordInputstream to read the record from
-     */
-    public MulBlankRecord(RecordInputStream in) {
-        field_1_row       = in.readUShort();
-        field_2_first_col = in.readShort();
-        field_3_xfs       = parseXFs(in);
-        field_4_last_col  = in.readShort();
-    }
-
-    private static short [] parseXFs(RecordInputStream in)
-    {
-        short[] retval = new short[ (in.remaining() - 2) / 2 ];
-
-        for (int idx = 0; idx < retval.length;idx++)
-        {
-          retval[idx] = in.readShort();
-        }
-        return retval;
-    }
-
-    public String toString() {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append("[MULBLANK]\n");
-        buffer.append("row  = ").append(Integer.toHexString(getRow())).append("\n");
-        buffer.append("firstcol  = ").append(Integer.toHexString(getFirstColumn())).append("\n");
-        buffer.append(" lastcol  = ").append(Integer.toHexString(getLastColumn())).append("\n");
-        for (int k = 0; k < getNumColumns(); k++) {
-            buffer.append("xf").append(k).append("        = ").append(
-                    Integer.toHexString(getXFAt(k))).append("\n");
-        }
-        buffer.append("[/MULBLANK]\n");
-        return buffer.toString();
-    }
-
-    public short getSid()
-    {
-        return sid;
-    }
-
-    public void serialize(LittleEndianOutput out) {
-        out.writeShort(field_1_row);
-        out.writeShort(field_2_first_col);
-        int nItems = field_3_xfs.length;
-        for (int i = 0; i < nItems; i++) {
-            out.writeShort(field_3_xfs[i]);
-        }
-        out.writeShort(field_4_last_col);
-    }
-
-    protected int getDataSize() {
-        // 3 short fields + array of shorts
-        return 6 + field_3_xfs.length * 2; 
-    }
+       public final static short sid = 0x00BE;
+
+       private final int _row;
+       private final int _firstCol;
+       private final short[] _xfs;
+       private final int _lastCol;
+
+       public MulBlankRecord(int row, int firstCol, short[] xfs) {
+               _row = row;
+               _firstCol = firstCol;
+               _xfs = xfs;
+               _lastCol = firstCol + xfs.length - 1;
+       }
+
+       /**
+        * @return the row number of the cells this represents
+        */
+       public int getRow() {
+               return _row;
+       }
+
+       /**
+        * @return starting column (first cell this holds in the row). Zero based
+        */
+       public int getFirstColumn() {
+               return _firstCol;
+       }
+
+       /**
+        * get the number of columns this contains (last-first +1)
+        * @return number of columns (last - first +1)
+        */
+       public int getNumColumns() {
+               return _lastCol - _firstCol + 1;
+       }
+
+       /**
+        * returns the xf index for column (coffset = column - field_2_first_col)
+        * @param coffset  the column (coffset = column - field_2_first_col)
+        * @return the XF index for the column
+        */
+       public short getXFAt(int coffset) {
+               return _xfs[coffset];
+       }
+
+       /**
+        * @param in the RecordInputstream to read the record from
+        */
+       public MulBlankRecord(RecordInputStream in) {
+               _row       = in.readUShort();
+               _firstCol = in.readShort();
+               _xfs       = parseXFs(in);
+               _lastCol  = in.readShort();
+       }
+
+       private static short [] parseXFs(RecordInputStream in) {
+               short[] retval = new short[(in.remaining() - 2) / 2];
+
+               for (int idx = 0; idx < retval.length;idx++) {
+                 retval[idx] = in.readShort();
+               }
+               return retval;
+       }
+
+       public String toString() {
+               StringBuffer buffer = new StringBuffer();
+
+               buffer.append("[MULBLANK]\n");
+               buffer.append("row  = ").append(Integer.toHexString(getRow())).append("\n");
+               buffer.append("firstcol  = ").append(Integer.toHexString(getFirstColumn())).append("\n");
+               buffer.append(" lastcol  = ").append(Integer.toHexString(_lastCol)).append("\n");
+               for (int k = 0; k < getNumColumns(); k++) {
+                       buffer.append("xf").append(k).append("          = ").append(
+                                       Integer.toHexString(getXFAt(k))).append("\n");
+               }
+               buffer.append("[/MULBLANK]\n");
+               return buffer.toString();
+       }
+
+       public short getSid() {
+               return sid;
+       }
+
+       public void serialize(LittleEndianOutput out) {
+               out.writeShort(_row);
+               out.writeShort(_firstCol);
+               int nItems = _xfs.length;
+               for (int i = 0; i < nItems; i++) {
+                       out.writeShort(_xfs[i]);
+               }
+               out.writeShort(_lastCol);
+       }
+
+       protected int getDataSize() {
+               // 3 short fields + array of shorts
+               return 6 + _xfs.length * 2;
+       }
+
+       @Override
+       public Object clone() {
+               // immutable - so OK to return this
+               return this;
+       }
 }
index 68ff2f6599204fad8c5f0d5852eebb0b50d269c8..a16c278e5a7e251d3073d276c8c8ace1d5384d03 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.hssf.model;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import junit.framework.AssertionFailedError;
@@ -34,6 +35,7 @@ import org.apache.poi.hssf.record.FormulaRecord;
 import org.apache.poi.hssf.record.GutsRecord;
 import org.apache.poi.hssf.record.IndexRecord;
 import org.apache.poi.hssf.record.MergeCellsRecord;
+import org.apache.poi.hssf.record.MulBlankRecord;
 import org.apache.poi.hssf.record.NumberRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.hssf.record.RecordBase;
@@ -629,11 +631,11 @@ public final class TestSheet extends TestCase {
                assertEquals(colIx, dims.getFirstCol());
                assertEquals(colIx, dims.getLastCol());
        }
-       
+
        /**
-        * Prior to the fix for bug 46547, shifting formulas would have the side-effect 
+        * Prior to the fix for bug 46547, shifting formulas would have the side-effect
         * of creating a {@link ConditionalFormattingTable}.  There was no impairment to
-        * functionality since empty record aggregates are equivalent to missing record 
+        * functionality since empty record aggregates are equivalent to missing record
         * aggregates. However, since this unnecessary creation helped expose bug 46547b,
         * and since there is a slight performance hit the fix was made to avoid it.
         */
@@ -643,14 +645,14 @@ public final class TestSheet extends TestCase {
 
                List<RecordBase> sheetRecs = sheet.getRecords();
                assertEquals(22, sheetRecs.size());
-               
+
                FormulaShifter shifter = FormulaShifter.createForRowShift(0, 0, 0, 1);
                sheet.updateFormulasAfterCellShift(shifter, 0);
                if (sheetRecs.size() == 23 && sheetRecs.get(21) instanceof ConditionalFormattingTable) {
                        throw new AssertionFailedError("Identified bug 46547a");
                }
                assertEquals(22, sheetRecs.size());
-               
+
        }
        /**
         * Bug 46547 happened when attempting to add conditional formatting to a sheet
@@ -671,4 +673,33 @@ public final class TestSheet extends TestCase {
                }
                assertNotNull(cft);
        }
+
+       public void testCloneMulBlank_bug46776() {
+               Record[]  recs = {
+                               Sheet.createBOF(),
+                               new DimensionsRecord(),
+                               new RowRecord(1),
+                               new MulBlankRecord(1, 3, new short[] { 0x0F, 0x0F, 0x0F, } ),
+                               new RowRecord(2),
+                               createWindow2Record(),
+                               EOFRecord.instance,
+               };
+
+               Sheet sheet = createSheet(Arrays.asList(recs));
+
+               Sheet sheet2;
+               try {
+                       sheet2 = sheet.cloneSheet();
+               } catch (RuntimeException e) {
+                       if (e.getMessage().equals("The class org.apache.poi.hssf.record.MulBlankRecord needs to define a clone method")) {
+                               throw new AssertionFailedError("Identified bug 46776");
+                       }
+                       throw e;
+               }
+
+               RecordCollector rc = new RecordCollector();
+               sheet2.visitContainedRecords(rc, 0);
+               Record[] clonedRecs = rc.getRecords();
+               assertEquals(recs.length+2, clonedRecs.length); // +2 for INDEX and DBCELL
+       }
 }