]> source.dussan.org Git - poi.git/commitdiff
Clean-up of copy/clone methods in Ptg hierarchy
authorJosh Micich <josh@apache.org>
Sun, 15 Nov 2009 09:01:35 +0000 (09:01 +0000)
committerJosh Micich <josh@apache.org>
Sun, 15 Nov 2009 09:01:35 +0000 (09:01 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@836343 13f79535-47bb-0310-9956-ffa450edef68

12 files changed:
src/java/org/apache/poi/hssf/record/SharedFormulaRecord.java
src/java/org/apache/poi/hssf/record/TextObjectRecord.java
src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java
src/java/org/apache/poi/hssf/record/formula/AreaPtgBase.java
src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
src/java/org/apache/poi/hssf/record/formula/OperandPtg.java
src/java/org/apache/poi/hssf/record/formula/Ptg.java
src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java
src/java/org/apache/poi/hssf/record/formula/RefPtgBase.java
src/java/org/apache/poi/hssf/record/formula/UnknownPtg.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/testcases/org/apache/poi/hssf/record/formula/TestFuncPtg.java

index 487829998164939cc126b9dee1fab2a2bf390690..c01cf77a3487e1e9979e7c8cbb32755cccec1ce7 100644 (file)
@@ -64,7 +64,7 @@ public final class SharedFormulaRecord extends SharedValueRecordBase {
         out.writeShort(field_5_reserved);
         field_7_parsed_expr.serialize(out);
     }
-    
+
     protected int getExtraDataSize() {
         return 2 + field_7_parsed_expr.getEncodedSize();
     }
@@ -98,8 +98,8 @@ public final class SharedFormulaRecord extends SharedValueRecordBase {
 
     /**
      * Creates a non shared formula from the shared formula counterpart<br/>
-     * 
-     * Perhaps this functionality could be implemented in terms of the raw 
+     *
+     * Perhaps this functionality could be implemented in terms of the raw
      * byte array inside {@link Formula}.
      */
     public static Ptg[] convertSharedFormulas(Ptg[] ptgs, int formulaRow, int formulaColumn) {
@@ -113,14 +113,15 @@ public final class SharedFormulaRecord extends SharedValueRecordBase {
                 originalOperandClass = ptg.getPtgClass();
             }
             if (ptg instanceof RefPtgBase) {
-              RefPtgBase refNPtg = (RefPtgBase)ptg;
-              ptg = new RefPtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
+                RefPtgBase refNPtg = (RefPtgBase)ptg;
+                ptg = new RefPtg(fixupRelativeRow(formulaRow,refNPtg.getRow(),refNPtg.isRowRelative()),
                                      fixupRelativeColumn(formulaColumn,refNPtg.getColumn(),refNPtg.isColRelative()),
                                      refNPtg.isRowRelative(),
                                      refNPtg.isColRelative());
+                ptg.setClass(originalOperandClass);
             } else if (ptg instanceof AreaPtgBase) {
-              AreaPtgBase areaNPtg = (AreaPtgBase)ptg;
-              ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()),
+                AreaPtgBase areaNPtg = (AreaPtgBase)ptg;
+                ptg = new AreaPtg(fixupRelativeRow(formulaRow,areaNPtg.getFirstRow(),areaNPtg.isFirstRowRelative()),
                                 fixupRelativeRow(formulaRow,areaNPtg.getLastRow(),areaNPtg.isLastRowRelative()),
                                 fixupRelativeColumn(formulaColumn,areaNPtg.getFirstColumn(),areaNPtg.isFirstColRelative()),
                                 fixupRelativeColumn(formulaColumn,areaNPtg.getLastColumn(),areaNPtg.isLastColRelative()),
@@ -128,15 +129,13 @@ public final class SharedFormulaRecord extends SharedValueRecordBase {
                                 areaNPtg.isLastRowRelative(),
                                 areaNPtg.isFirstColRelative(),
                                 areaNPtg.isLastColRelative());
-            } else {
-                if (false) {// do we need a ptg clone here?
-                    ptg = ptg.copy();
-                }
-            }
-            if (!ptg.isBaseToken()) {
                 ptg.setClass(originalOperandClass);
+            } else if (ptg instanceof OperandPtg<?>) {
+                // Any subclass of OperandPtg is mutable, so it's safest to not share these instances.
+                ptg = ((OperandPtg<?>) ptg).copy();
+            } else {
+               // all other Ptgs are immutable and can be shared
             }
-
             newPtgStack[k] = ptg;
         }
         return newPtgStack;
index 06fb3e431956fb3aa7feb2f46607c9600f3543a1..68398bb70cb6c2b96fed9cc9d4af5e1b6dc25a8f 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.hssf.record;
 
 import org.apache.poi.hssf.record.cont.ContinuableRecord;
 import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
+import org.apache.poi.hssf.record.formula.OperandPtg;
 import org.apache.poi.hssf.record.formula.Ptg;
 import org.apache.poi.hssf.usermodel.HSSFRichTextString;
 import org.apache.poi.util.BitField;
@@ -74,13 +75,14 @@ public final class TextObjectRecord extends ContinuableRecord {
         */
        private int _unknownPreFormulaInt;
        /** expect tRef, tRef3D, tArea, tArea3D or tName */
-       private Ptg _linkRefPtg;
+       private OperandPtg<?> _linkRefPtg;
        /**
         * Not clear if needed .  Excel seems to be OK if this byte is not present.
         * Value is often the same as the earlier firstColumn byte. */
        private Byte _unknownPostFormulaByte;
 
        public TextObjectRecord() {
+               //
        }
 
        public TextObjectRecord(RecordInputStream in) {
@@ -106,7 +108,7 @@ public final class TextObjectRecord extends ContinuableRecord {
                                throw new RecordFormatException("Read " + ptgs.length
                                                + " tokens but expected exactly 1");
                        }
-                       _linkRefPtg = ptgs[0];
+                       _linkRefPtg = (OperandPtg<?>) ptgs[0];
                        if (in.remaining() > 0) {
                                _unknownPostFormulaByte = Byte.valueOf(in.readByte());
                        } else {
index aec3e03503b29f2ba067c200ca8120afc4850d42..264b448ca62e63cc5c13413937adbf46b714ece3 100644 (file)
@@ -32,10 +32,10 @@ import org.apache.poi.util.LittleEndianOutput;
  * @author avik
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public final class Area3DPtg extends AreaPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken {
+public final class Area3DPtg extends AreaPtgBase<Area3DPtg> implements WorkbookDependentFormula, ExternSheetReferenceToken {
        public final static byte sid = 0x3b;
        private final static int SIZE = 11; // 10 + 1 for Ptg
-       
+
        private int field_1_index_extern_sheet;
 
 
index 5cd5a9b74858242d78b1434bb34b37e66da7ede1..d50fca02f9bea3258c6f55938d8a35d8e9d5a871 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.poi.util.LittleEndianOutput;
  * @author  andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public abstract class AreaPtgBase extends OperandPtg implements AreaI {
+public abstract class AreaPtgBase<Z extends AreaPtgBase<Z>> extends OperandPtg<Z> implements AreaI {
        /**
         * TODO - (May-2008) fix subclasses of AreaPtg 'AreaN~' which are used in shared formulas.
         * see similar comment in ReferencePtg
@@ -96,17 +96,6 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
                }
        }
 
-       private static void $checkColumnBounds(int colIx) {
-               if((colIx & 0x0FF) != colIx) {
-                       throw new IllegalArgumentException("colIx (" + colIx + ") is out of range");
-               }
-       }
-       private static void $checkRowBounds(int rowIx) {
-               if((rowIx & 0x0FFFF) != rowIx) {
-                       throw new IllegalArgumentException("rowIx (" + rowIx + ") is out of range");
-               }
-       }
-
        protected final void readCoordinates(LittleEndianInput in)  {
                field_1_first_row = in.readUShort();
                field_2_last_row = in.readUShort();
index 5cec763e1341ccca0e4b7467f50857dc5ef26c4a..bbfb95a729d33f28f841ead50d2c85f1ca570100 100644 (file)
@@ -260,14 +260,4 @@ public final class AttrPtg extends ControlPtg {
       }
       return "UNKNOWN ATTRIBUTE";
      }
-
-    public Object clone() {
-        int[] jt;
-        if (_jumpTable == null) {
-            jt = null;
-        } else {
-            jt = _jumpTable.clone();
-        }
-        return new AttrPtg(_options, _data, jt, _chooseFuncOffset);
-    }
 }
index 0c1d1faeb865edefff4d1861846bc781c37169ac..bd1490289ca2678f72f5e3295fe163641045dc26 100644 (file)
@@ -21,12 +21,21 @@ package org.apache.poi.hssf.record.formula;
 /**
  * @author Josh Micich
  */
-public abstract class OperandPtg extends Ptg {
+public abstract class OperandPtg<Y extends OperandPtg<Y>> extends Ptg implements Cloneable {
 
        /**
-        * All Operand <tt>Ptg</tt>s are classifed ('relative', 'value', 'array')  
+        * All Operand {@link Ptg}s are classified ('relative', 'value', 'array')
         */
        public final boolean isBaseToken() {
                return false;
        }
+       public final Y copy() {
+               try {
+                       @SuppressWarnings("unchecked")
+                       Y result = (Y) clone();
+                       return result;
+               } catch (CloneNotSupportedException e) {
+                       throw new RuntimeException(e);
+               }
+       }
 }
index f2857a7dfa480770c11abfe462e6a52d943e1591..2426249c15788257fc8488903f5a8ce4ee8e2347 100644 (file)
@@ -40,7 +40,7 @@ import org.apache.poi.util.LittleEndianOutput;
  * @author avik
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public abstract class Ptg implements Cloneable {
+public abstract class Ptg {
        public static final Ptg[] EMPTY_PTG_ARRAY = { };
 
 
@@ -158,28 +158,7 @@ public abstract class Ptg implements Cloneable {
                }
                throw new RuntimeException("Unexpected base token id (" + id + ")");
        }
-       /**
-        * @return a distinct copy of this <tt>Ptg</tt> if the class is mutable, or the same instance
-        * if the class is immutable.
-        */
-       public final Ptg copy() {
-               // TODO - all base tokens are logically immutable, but AttrPtg needs some clean-up
-               if (this instanceof ValueOperatorPtg) {
-                       return this;
-               }
-               if (this instanceof ScalarConstantPtg) {
-                       return this;
-               }
-               return (Ptg) clone();
-       }
 
-       protected Object clone() {
-               try {
-                       return super.clone();
-               } catch (CloneNotSupportedException e) {
-                       throw new RuntimeException(e);
-               }
-       }
        private static Ptg[] toPtgArray(List<Ptg> l) {
                if (l.isEmpty()) {
                        return EMPTY_PTG_ARRAY;
index c695932a1ca18dc7155b2e8fbc0e5701dec3a49b..13a7f05899ff7058dc1fbf3674617f11d4855801 100644 (file)
@@ -31,7 +31,7 @@ import org.apache.poi.util.LittleEndianOutput;
  * @author Libin Roman (Vista Portal LDT. Developer)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken {
+public final class Ref3DPtg extends RefPtgBase<Ref3DPtg> implements WorkbookDependentFormula, ExternSheetReferenceToken {
     public final static byte sid  = 0x3a;
 
     private final static int  SIZE = 7; // 6 + 1 for Ptg
@@ -42,7 +42,7 @@ public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormu
         field_1_index_extern_sheet = in.readShort();
         readCoordinates(in);
     }
-    
+
     public Ref3DPtg(String cellref, int externIdx ) {
         this(new CellReference(cellref), externIdx);
     }
@@ -82,7 +82,7 @@ public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormu
     }
 
     /**
-     * @return text representation of this cell reference that can be used in text 
+     * @return text representation of this cell reference that can be used in text
      * formulas. The sheet name will get properly delimited if required.
      */
     public String toFormulaString(FormulaRenderingWorkbook book) {
index 70ed4da87ac1d816609bcd4ebebb3da2f97facf5..28e7ebd9fb15cdf600648a900328876de2693b39 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.poi.util.LittleEndianOutput;
  * @author Andrew C. Oliver (acoliver@apache.org)
  * @author Jason Height (jheight at chariot dot net dot au)
  */
-public abstract class RefPtgBase extends OperandPtg {
+public abstract class RefPtgBase<Z extends RefPtgBase<Z>> extends OperandPtg<Z> {
 
        /** The row index - zero based unsigned 16 bit value */
        private int field_1_row;
index d441a0098d56169c7fb468d18dc64c7cd97e03c0..ca94766a5e226eb3745f223355a37ca1f72d9448 100644 (file)
@@ -19,8 +19,7 @@ package org.apache.poi.hssf.record.formula;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- *
- * @author  andy
+ * @author andy
  * @author Jason Height (jheight at chariot dot net dot au)
  */
 public class UnknownPtg extends Ptg {
@@ -38,18 +37,14 @@ public class UnknownPtg extends Ptg {
         out.writeByte(_sid);
     }
 
-    public int getSize()
-    {
+    public int getSize() {
         return size;
     }
 
-    public String toFormulaString()
-    {
+    public String toFormulaString() {
         return "UNKNOWN";
     }
-    public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
-
-    public Object clone() {
-      return this;
+    public byte getDefaultOperandClass() {
+        return Ptg.CLASS_VALUE;
     }
 }
index 3d81c478f4aa254a9f330bee252587628ef41a2f..612eb67b18f9d383741f50f49414716b1eb8a670 100644 (file)
@@ -676,16 +676,16 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm
             Ptg[] ptgs = origNameRecord.getNameDefinition();
             for (int i=0; i< ptgs.length; i++) {
                 Ptg ptg = ptgs[i];
-                ptg = ptg.copy();
 
                 if (ptg instanceof Area3DPtg) {
-                    Area3DPtg a3p = (Area3DPtg) ptg;
+                    Area3DPtg a3p = ((Area3DPtg) ptg).copy();
                     a3p.setExternSheetIndex(newExtSheetIx);
+                    ptgs[i] = a3p;
                 } else if (ptg instanceof Ref3DPtg) {
-                    Ref3DPtg r3p = (Ref3DPtg) ptg;
+                    Ref3DPtg r3p = ((Ref3DPtg) ptg).copy();
                     r3p.setExternSheetIndex(newExtSheetIx);
+                    ptgs[i] = r3p;
                 }
-                ptgs[i] = ptg;
             }
             NameRecord newNameRecord = workbook.createBuiltInName(NameRecord.BUILTIN_FILTER_DB, newSheetIndex+1);
             newNameRecord.setNameDefinition(ptgs);
index 399e80c240d8c2b063db2b786bbef6e4bc3165f0..52121728c3aef71a79a0f1f8e16e080d41da3584 100644 (file)
@@ -28,11 +28,8 @@ import org.apache.poi.hssf.record.TestcaseRecordInputStream;
 public final class TestFuncPtg extends TestCase {
 
     public void testRead() {
-       // This ptg represents a LEN function extracted from excel
-        byte[] fakeData = {
-            0x20,  //function index
-            0,
-        };
+       // This function index represents the LEN() function
+        byte[] fakeData = { 0x20, 0x00,};
 
         FuncPtg ptg = FuncPtg.create(TestcaseRecordInputStream.createLittleEndian(fakeData) );
         assertEquals( "Len formula index is not 32(20H)", 0x20, ptg.getFunctionIndex() );
@@ -41,14 +38,9 @@ public final class TestFuncPtg extends TestCase {
         assertEquals( "Ptg Size", 3, ptg.getSize() );
     }
 
-    public void testClone() {
+    public void testNumberOfOperands() {
         FuncPtg funcPtg = FuncPtg.create(27); // ROUND() - takes 2 args
-
-        FuncPtg clone = (FuncPtg) funcPtg.clone();
-        if (clone.getNumberOfOperands() == 0) {
-            fail("clone() did copy field numberOfOperands");
-        }
-        assertEquals(2, clone.getNumberOfOperands());
-        assertEquals("ROUND", clone.getName());
+        assertEquals(2, funcPtg.getNumberOfOperands());
+        assertEquals("ROUND", funcPtg.getName());
     }
 }