]> source.dussan.org Git - poi.git/commitdiff
Introduce a CFHeaderBase common parent #58130
authorNick Burch <nick@apache.org>
Sun, 12 Jul 2015 18:35:33 +0000 (18:35 +0000)
committerNick Burch <nick@apache.org>
Sun, 12 Jul 2015 18:35:33 +0000 (18:35 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1690503 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/CFHeader12Record.java
src/java/org/apache/poi/hssf/record/CFHeaderBase.java [new file with mode: 0644]
src/java/org/apache/poi/hssf/record/CFHeaderRecord.java
src/testcases/org/apache/poi/hssf/record/TestCFHeaderRecord.java

index 22b165af4e50646c739650b653cdcdd9e8663118..8559be9b076bef77d619035ff2489e1c53c2a5d2 100644 (file)
@@ -25,14 +25,14 @@ import org.apache.poi.util.LittleEndianOutput;
  * Conditional Formatting Header v12 record CFHEADER12 (0x0879),
  *  for conditional formattings introduced in Excel 2007 and newer.
  */
-public final class CFHeader12Record extends CFHeaderRecord {
+public final class CFHeader12Record extends CFHeaderBase {
     public static final short sid = 0x0879;
 
     private FtrHeader futureHeader;
 
     /** Creates new CFHeaderRecord */
     public CFHeader12Record() {
-        super();
+        createEmpty();
         futureHeader = new FtrHeader();
         futureHeader.setRecordType(sid);
     }
@@ -41,9 +41,7 @@ public final class CFHeader12Record extends CFHeaderRecord {
         futureHeader = new FtrHeader();
         futureHeader.setRecordType(sid);
     }
-
-    public CFHeader12Record(RecordInputStream in)
-    {
+    public CFHeader12Record(RecordInputStream in) {
         futureHeader = new FtrHeader(in);
         read(in);
     }
@@ -69,7 +67,7 @@ public final class CFHeader12Record extends CFHeaderRecord {
     public Object clone() {
         CFHeader12Record result = new CFHeader12Record();
         result.futureHeader = (FtrHeader)futureHeader.clone();
-        // TODO Clone the rest via the base
+        super.copyTo(result);
         return result;
     }
 }
diff --git a/src/java/org/apache/poi/hssf/record/CFHeaderBase.java b/src/java/org/apache/poi/hssf/record/CFHeaderBase.java
new file mode 100644 (file)
index 0000000..4e40a34
--- /dev/null
@@ -0,0 +1,153 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.hssf.record.cf.CellRangeUtil;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Parent of Conditional Formatting Header records,
+ *  {@link CFHeaderRecord} and {@link CFHeader12Record}.
+ */
+public abstract class CFHeaderBase extends StandardRecord {
+    private int field_1_numcf;
+    private int field_2_need_recalculation_and_id;
+    private CellRangeAddress field_3_enclosing_cell_range;
+    private CellRangeAddressList field_4_cell_ranges;
+
+    /** Creates new CFHeaderBase */
+    protected CFHeaderBase() {
+    }
+    protected CFHeaderBase(CellRangeAddress[] regions, int nRules) {
+        CellRangeAddress[] unmergedRanges = regions;
+        CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges);
+        setCellRanges(mergeCellRanges);
+        field_1_numcf = nRules;
+    }
+
+    protected void createEmpty() {
+        field_3_enclosing_cell_range = new CellRangeAddress(0, 0, 0, 0);
+        field_4_cell_ranges = new CellRangeAddressList();
+    }
+    protected void read(RecordInputStream in) {
+        field_1_numcf = in.readShort();
+        field_2_need_recalculation_and_id = in.readShort();
+        field_3_enclosing_cell_range = new CellRangeAddress(in);
+        field_4_cell_ranges = new CellRangeAddressList(in);
+    }
+
+    public int getNumberOfConditionalFormats() {
+        return field_1_numcf;
+    }
+    public void setNumberOfConditionalFormats(int n) {
+        field_1_numcf=n;
+    }
+
+    public boolean getNeedRecalculation() {
+        // Held on the 1st bit
+        return field_2_need_recalculation_and_id % 2 == 1;
+    }
+    public void setNeedRecalculation(boolean b) {
+        // held on the first bit
+        if (b == getNeedRecalculation()) return;
+        if (b) field_2_need_recalculation_and_id++;
+        else   field_2_need_recalculation_and_id--;
+    }
+
+    public int getID() {
+        // Remaining 15 bits of field 2
+        return field_2_need_recalculation_and_id>>1;
+    }
+    public void setID(int id) {
+        // Remaining 15 bits of field 2
+        boolean needsRecalc = getNeedRecalculation();
+        field_2_need_recalculation_and_id = (id<<1);
+        if (needsRecalc) field_2_need_recalculation_and_id++;
+    }
+
+    public CellRangeAddress getEnclosingCellRange() {
+        return field_3_enclosing_cell_range;
+    }
+    public void setEnclosingCellRange(CellRangeAddress cr) {
+        field_3_enclosing_cell_range = cr;
+    }
+
+    /**
+     * Set cell ranges list to a single cell range and 
+     * modify the enclosing cell range accordingly.
+     * @param cellRanges - list of CellRange objects
+     */
+    public void setCellRanges(CellRangeAddress[] cellRanges) {
+        if(cellRanges == null) {
+            throw new IllegalArgumentException("cellRanges must not be null");
+        }
+        CellRangeAddressList cral = new CellRangeAddressList();
+        CellRangeAddress enclosingRange = null;
+        for (int i = 0; i < cellRanges.length; i++) {
+            CellRangeAddress cr = cellRanges[i];
+            enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange);
+            cral.addCellRangeAddress(cr);
+        }
+        field_3_enclosing_cell_range = enclosingRange;
+        field_4_cell_ranges = cral;
+    }
+
+    public CellRangeAddress[] getCellRanges() {
+        return field_4_cell_ranges.getCellRangeAddresses();
+    }
+
+    protected abstract String getRecordName();
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[").append(getRecordName()).append("]\n");
+        buffer.append("\t.numCF             = ").append(getNumberOfConditionalFormats()).append("\n");
+        buffer.append("\t.needRecalc        = ").append(getNeedRecalculation()).append("\n");
+        buffer.append("\t.id                = ").append(getID()).append("\n");
+        buffer.append("\t.enclosingCellRange= ").append(getEnclosingCellRange()).append("\n");
+        buffer.append("\t.cfranges=[");
+        for( int i=0; i<field_4_cell_ranges.countRanges(); i++) {
+            buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
+        }
+        buffer.append("]\n");
+        buffer.append("[/").append(getRecordName()).append("]\n");
+        return buffer.toString();
+    }
+
+    protected int getDataSize() {
+        return 4 // 2 short fields
+             + CellRangeAddress.ENCODED_SIZE
+             + field_4_cell_ranges.getSize();
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.writeShort(field_1_numcf);
+        out.writeShort(field_2_need_recalculation_and_id);
+        field_3_enclosing_cell_range.serialize(out);
+        field_4_cell_ranges.serialize(out);
+    }
+
+    protected void copyTo(CFHeaderBase result) {
+        result.field_1_numcf = field_1_numcf;
+        result.field_2_need_recalculation_and_id = field_2_need_recalculation_and_id;
+        result.field_3_enclosing_cell_range = field_3_enclosing_cell_range.copy();
+        result.field_4_cell_ranges = field_4_cell_ranges.copy();
+    }
+}
index b12c869f4ea9f1280c48f6f259b690f1771aec0a..a456224a7091f682bf7c229cf743faba233689ea 100644 (file)
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.hssf.record.cf.CellRangeUtil;
 import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.CellRangeAddressList;
-import org.apache.poi.util.LittleEndianOutput;
 
 /**
  * Conditional Formatting Header record CFHEADER (0x01B0).
  * Used to describe a {@link CFRuleRecord}.
  * @see CFHeader12Record
- * TODO Move most of the logic into a base class
  */
-public class CFHeaderRecord extends StandardRecord {
+public final class CFHeaderRecord extends CFHeaderBase {
     public static final short sid = 0x01B0;
 
-    private int field_1_numcf;
-    private int field_2_need_recalculation_and_id;
-    private CellRangeAddress field_3_enclosing_cell_range;
-    private CellRangeAddressList field_4_cell_ranges;
-
     /** Creates new CFHeaderRecord */
     public CFHeaderRecord() {
-        field_3_enclosing_cell_range = new CellRangeAddress(0, 0, 0, 0);
-        field_4_cell_ranges = new CellRangeAddressList();
+        createEmpty();
     }
     public CFHeaderRecord(CellRangeAddress[] regions, int nRules) {
-        CellRangeAddress[] unmergedRanges = regions;
-        CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges);
-        setCellRanges(mergeCellRanges);
-        field_1_numcf = nRules;
+        super(regions, nRules);
     }
 
     public CFHeaderRecord(RecordInputStream in) {
         read(in);
     }
-    protected void read(RecordInputStream in) {
-        field_1_numcf = in.readShort();
-        field_2_need_recalculation_and_id = in.readShort();
-        field_3_enclosing_cell_range = new CellRangeAddress(in);
-        field_4_cell_ranges = new CellRangeAddressList(in);
-    }
-
-    public int getNumberOfConditionalFormats() {
-        return field_1_numcf;
-    }
-    public void setNumberOfConditionalFormats(int n) {
-        field_1_numcf=n;
-    }
-
-    public boolean getNeedRecalculation() {
-        // Held on the 1st bit
-        return field_2_need_recalculation_and_id % 2 == 1;
-    }
-    public void setNeedRecalculation(boolean b) {
-        // held on the first bit
-        if (b == getNeedRecalculation()) return;
-        if (b) field_2_need_recalculation_and_id++;
-        else   field_2_need_recalculation_and_id--;
-    }
-
-    public int getID() {
-        // Remaining 15 bits of field 2
-        return field_2_need_recalculation_and_id>>1;
-    }
-    public void setID(int id) {
-        // Remaining 15 bits of field 2
-        boolean needsRecalc = getNeedRecalculation();
-        field_2_need_recalculation_and_id = (id<<1);
-        if (needsRecalc) field_2_need_recalculation_and_id++;
-    }
-
-    public CellRangeAddress getEnclosingCellRange() {
-        return field_3_enclosing_cell_range;
-    }
-    public void setEnclosingCellRange(CellRangeAddress cr) {
-        field_3_enclosing_cell_range = cr;
-    }
-
-    /**
-     * Set cell ranges list to a single cell range and 
-     * modify the enclosing cell range accordingly.
-     * @param cellRanges - list of CellRange objects
-     */
-    public void setCellRanges(CellRangeAddress[] cellRanges) {
-        if(cellRanges == null) {
-            throw new IllegalArgumentException("cellRanges must not be null");
-        }
-        CellRangeAddressList cral = new CellRangeAddressList();
-        CellRangeAddress enclosingRange = null;
-        for (int i = 0; i < cellRanges.length; i++) {
-            CellRangeAddress cr = cellRanges[i];
-            enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange);
-            cral.addCellRangeAddress(cr);
-        }
-        field_3_enclosing_cell_range = enclosingRange;
-        field_4_cell_ranges = cral;
-    }
-
-    public CellRangeAddress[] getCellRanges() {
-        return field_4_cell_ranges.getCellRangeAddresses();
-    }
 
     protected String getRecordName() {
         return "CFHEADER";
     }
-    public String toString() {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append("[").append(getRecordName()).append("]\n");
-        buffer.append("        .id             = ").append(Integer.toHexString(sid)).append("\n");
-        buffer.append("        .numCF                  = ").append(getNumberOfConditionalFormats()).append("\n");
-        buffer.append("        .needRecalc        = ").append(getNeedRecalculation()).append("\n");
-        buffer.append("        .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n");
-        buffer.append("        .cfranges=[");
-        for( int i=0; i<field_4_cell_ranges.countRanges(); i++) {
-            buffer.append(i==0?"":",").append(field_4_cell_ranges.getCellRangeAddress(i).toString());
-        }
-        buffer.append("]\n");
-        buffer.append("[/").append(getRecordName()).append("]\n");
-        return buffer.toString();
-    }
-
-    protected int getDataSize() {
-        return 4 // 2 short fields
-             + CellRangeAddress.ENCODED_SIZE
-             + field_4_cell_ranges.getSize();
-    }
-
-    public void serialize(LittleEndianOutput out) {
-        out.writeShort(field_1_numcf);
-        out.writeShort(field_2_need_recalculation_and_id);
-        field_3_enclosing_cell_range.serialize(out);
-        field_4_cell_ranges.serialize(out);
-    }
 
     public short getSid() {
         return sid;
@@ -157,10 +49,7 @@ public class CFHeaderRecord extends StandardRecord {
 
     public Object clone() {
         CFHeaderRecord result = new CFHeaderRecord();
-        result.field_1_numcf = field_1_numcf;
-        result.field_2_need_recalculation_and_id = field_2_need_recalculation_and_id;
-        result.field_3_enclosing_cell_range = field_3_enclosing_cell_range.copy();
-        result.field_4_cell_ranges = field_4_cell_ranges.copy();
+        super.copyTo(result);
         return result;
     }
 }
index 239f2092f714825d9efc0e7de2813c3ef1475a17..9c9b5486cf42a66b7fb956967538a6e20d0c0b95 100644 (file)
@@ -23,16 +23,11 @@ import junit.framework.TestCase;
 import org.apache.poi.ss.util.CellRangeAddress;
 
 /**
- * Tests the serialization and deserialization of the TestCFHeaderRecord
- * class works correctly.  
- *
- * @author Dmitriy Kumshayev 
+ * Tests the serialization and deserialization of the {@link CFHeaderRecord}
+ *  and {@link CFHeader12Record} classes works correctly.  
  */
-public final class TestCFHeaderRecord extends TestCase
-{
-
-       public void testCreateCFHeaderRecord () 
-       {
+public final class TestCFHeaderRecord extends TestCase {
+       public void testCreateCFHeaderRecord () {
                CFHeaderRecord record = new CFHeaderRecord();
                CellRangeAddress[] ranges = {
                        new CellRangeAddress(0,0xFFFF,5,5),
@@ -50,12 +45,52 @@ public final class TestCFHeaderRecord extends TestCase
                assertEquals(65535, enclosingCellRange.getLastRow());
                assertEquals(0, enclosingCellRange.getFirstColumn());
                assertEquals(6, enclosingCellRange.getLastColumn());
+               
+               assertEquals(false, record.getNeedRecalculation());
+               assertEquals(0, record.getID());
+               
                record.setNeedRecalculation(true);
-               assertTrue(record.getNeedRecalculation());
+        assertEquals(true, record.getNeedRecalculation());
+        assertEquals(0, record.getID());
+        
+        record.setID(7);
                record.setNeedRecalculation(false);
-               assertFalse(record.getNeedRecalculation());
+        assertEquals(false, record.getNeedRecalculation());
+        assertEquals(7, record.getID());
        }
        
+    public void testCreateCFHeader12Record () {
+        CFHeader12Record record = new CFHeader12Record();
+        CellRangeAddress[] ranges = {
+            new CellRangeAddress(0,0xFFFF,5,5),
+            new CellRangeAddress(0,0xFFFF,6,6),
+            new CellRangeAddress(0,1,0,1),
+            new CellRangeAddress(0,1,2,3),
+            new CellRangeAddress(2,3,0,1),
+            new CellRangeAddress(2,3,2,3),
+        };
+        record.setCellRanges(ranges);
+        ranges = record.getCellRanges();
+        assertEquals(6,ranges.length);
+        CellRangeAddress enclosingCellRange = record.getEnclosingCellRange();
+        assertEquals(0, enclosingCellRange.getFirstRow());
+        assertEquals(65535, enclosingCellRange.getLastRow());
+        assertEquals(0, enclosingCellRange.getFirstColumn());
+        assertEquals(6, enclosingCellRange.getLastColumn());
+
+        assertEquals(false, record.getNeedRecalculation());
+        assertEquals(0, record.getID());
+        
+        record.setNeedRecalculation(true);
+        assertEquals(true, record.getNeedRecalculation());
+        assertEquals(0, record.getID());
+        
+        record.setID(7);
+        record.setNeedRecalculation(false);
+        assertEquals(false, record.getNeedRecalculation());
+        assertEquals(7, record.getID());
+    }
+    
        public void testSerialization() {
                byte[] recordData = 
                {