You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2019/12/22 21:44:48 UTC

svn commit: r1871911 [4/15] - in /poi/trunk/src: integrationtest/org/apache/poi/ integrationtest/org/apache/poi/hssf/usermodel/ java/org/apache/poi/common/ java/org/apache/poi/ddf/ java/org/apache/poi/hssf/eventusermodel/dummyrecord/ java/org/apache/po...

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FileSharingRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FileSharingRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FileSharingRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FileSharingRecord.java Sun Dec 22 21:44:45 2019
@@ -18,17 +18,16 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 import org.apache.poi.util.StringUtil;
 
 /**
- * Title:        FILESHARING (0x005B) <p>
- * Description:  stores the encrypted readonly for a workbook (write protect) 
- * This functionality is accessed from the options dialog box available when performing 'Save As'.<p>
- * REFERENCE:  PG 314 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Stores the encrypted readonly for a workbook (write protect).<p>
+ * This functionality is accessed from the options dialog box available when performing 'Save As'.
  */
-public final class FileSharingRecord extends StandardRecord implements Cloneable {
+public final class FileSharingRecord extends StandardRecord {
 
-    public final static short sid = 0x005B;
+    public static final short sid = 0x005B;
     private short             field_1_readonly;
     private short             field_2_password;
     private byte              field_3_username_unicode_options;
@@ -36,14 +35,22 @@ public final class FileSharingRecord ext
 
     public FileSharingRecord() {}
 
+    public FileSharingRecord(FileSharingRecord other) {
+        super(other);
+        field_1_readonly = other.field_1_readonly;
+        field_2_password = other.field_2_password;
+        field_3_username_unicode_options = other.field_3_username_unicode_options;
+        field_3_username_value = other.field_3_username_value;
+    }
+
     public FileSharingRecord(RecordInputStream in) {
         field_1_readonly = in.readShort();
         field_2_password = in.readShort();
-        
+
         int nameLen = in.readShort();
-        
+
         if(nameLen > 0) {
-            // TODO - Current examples(3) from junits only have zero length username. 
+            // TODO - Current examples(3) from junits only have zero length username.
             field_3_username_unicode_options = in.readByte();
             field_3_username_value = in.readCompressedUnicode(nameLen);
         } else {
@@ -137,11 +144,15 @@ public final class FileSharingRecord ext
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public FileSharingRecord clone() {
-      FileSharingRecord clone = new FileSharingRecord();
-      clone.setReadOnly(field_1_readonly);
-      clone.setPassword(field_2_password);
-      clone.setUsername(field_3_username_value);
-      return clone;
+        return copy();
+    }
+
+    @Override
+    public FileSharingRecord copy() {
+      return new FileSharingRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FnGroupCountRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FnGroupCountRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FnGroupCountRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FnGroupCountRecord.java Sun Dec 22 21:44:45 2019
@@ -15,35 +15,32 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title: Function Group Count Record<P>
- * Description:  Number of built in function groups in the current version of the
- *               Spreadsheet (probably only used on Windoze)<P>
- * REFERENCE:  PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
+ * umber of built in function groups in the current version of the Spreadsheet (probably only used on Windows)
+ *
  * @version 2.0-pre
  */
-
-public final class FnGroupCountRecord
-    extends StandardRecord
-{
-    public final static short sid   = 0x9c;
+public final class FnGroupCountRecord extends StandardRecord {
+    public static final short sid   = 0x9c;
 
     /**
      * suggested default (14 dec)
      */
 
-    public final static short COUNT = 14;
+    public static final short COUNT = 14;
     private short             field_1_count;
 
-    public FnGroupCountRecord()
-    {
+    public FnGroupCountRecord() {}
+
+    public FnGroupCountRecord(FnGroupCountRecord other) {
+        super(other);
+        field_1_count = other.field_1_count;
     }
 
     public FnGroupCountRecord(RecordInputStream in)
@@ -96,4 +93,9 @@ public final class FnGroupCountRecord
     {
         return sid;
     }
+
+    @Override
+    public FnGroupCountRecord copy() {
+        return new FnGroupCountRecord(this);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java Sun Dec 22 21:44:45 2019
@@ -25,50 +25,68 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
-/**
- * Title:        Font Record (0x0031) <p>
- * - describes a font in the workbook (index = 0-3,5-infinity - skip 4)<P>
- * Description:  An element in the Font Table<p>
- * REFERENCE:  PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
- */
+/** Describes a font in the workbook */
 public final class FontRecord extends StandardRecord {
 	// docs are wrong (0x231 Microsoft Support site article Q184647)
-	public final static short     sid                 = 0x0031;
-	public final static short     SS_NONE             = 0;
-	public final static short     SS_SUPER            = 1;
-	public final static short     SS_SUB              = 2;
-	public final static byte      U_NONE              = 0;
-	public final static byte      U_SINGLE            = 1;
-	public final static byte      U_DOUBLE            = 2;
-	public final static byte      U_SINGLE_ACCOUNTING = 0x21;
-	public final static byte      U_DOUBLE_ACCOUNTING = 0x22;
-	// in units of .05 of a point
-	private short                 field_1_font_height;
-	private short                 field_2_attributes;
+	public static final short sid                = 0x0031;
+	public static final short SS_NONE            = 0;
+	public static final short SS_SUPER           = 1;
+	public static final short SS_SUB             = 2;
+	public static final byte U_NONE              = 0;
+	public static final byte U_SINGLE            = 1;
+	public static final byte U_DOUBLE            = 2;
+	public static final byte U_SINGLE_ACCOUNTING = 0x21;
+	public static final byte U_DOUBLE_ACCOUNTING = 0x22;
 
 	// 0 0x01 - Reserved bit must be 0
-	private static final BitField italic     = BitFieldFactory.getInstance(0x02); // is this font in italics
+	// is this font in italics
+	private static final BitField italic     = BitFieldFactory.getInstance(0x02);
 
 	// 2 0x04 - reserved bit must be 0
-	private static final BitField strikeout  =BitFieldFactory.getInstance(0x08);  // is this font has a line through the center
-	private static final BitField macoutline = BitFieldFactory.getInstance(0x10); // some weird macintosh thing....but who understands those mac people anyhow
-	private static final BitField macshadow  = BitFieldFactory.getInstance(0x20); // some weird macintosh thing....but who understands those mac people anyhow
+	// is this font has a line through the center
+	private static final BitField strikeout  = BitFieldFactory.getInstance(0x08);
+	// some weird macintosh thing....but who understands those mac people anyhow
+	private static final BitField macoutline = BitFieldFactory.getInstance(0x10);
+	private static final BitField macshadow  = BitFieldFactory.getInstance(0x20);
+
+	// in units of .05 of a point
+	private short field_1_font_height;
+	private short field_2_attributes;
 
 	// 7-6 - reserved bits must be 0
 	// the rest is unused
-	private short                 field_3_color_palette_index;
-	private short                 field_4_bold_weight;
-	private short                 field_5_super_sub_script;   // 00none/01super/02sub
-	private byte                  field_6_underline;          // 00none/01single/02double/21singleaccounting/22doubleaccounting
-	private byte                  field_7_family;             // ?? defined by windows api logfont structure?
-	private byte                  field_8_charset;            // ?? defined by windows api logfont structure?
-	private byte                  field_9_zero;           // must be 0
+	private short field_3_color_palette_index;
+	private short field_4_bold_weight;
+	// 00none/01super/02sub
+	private short field_5_super_sub_script;
+	// 00none/01single/02double/21singleaccounting/22doubleaccounting
+	private byte field_6_underline;
+	// ?? defined by windows api logfont structure?
+	private byte field_7_family;
+	// ?? defined by windows api logfont structure?
+	private byte field_8_charset;
+	// must be 0
+	private byte field_9_zero;
 	/** possibly empty string never <code>null</code> */
-	private String                field_11_font_name;
+	private String field_11_font_name;
 
 	public FontRecord() {
 	}
 
+	public FontRecord(FontRecord other) {
+		super(other);
+		field_1_font_height = other.field_1_font_height;
+		field_2_attributes = other.field_2_attributes;
+		field_3_color_palette_index = other.field_3_color_palette_index;
+		field_4_bold_weight = other.field_4_bold_weight;
+		field_5_super_sub_script = other.field_5_super_sub_script;
+		field_6_underline = other.field_6_underline;
+		field_7_family = other.field_7_family;
+		field_8_charset = other.field_8_charset;
+		field_9_zero = other.field_9_zero;
+		field_11_font_name = other.field_11_font_name;
+	}
+
 	public FontRecord(RecordInputStream in) {
 		field_1_font_height         = in.readShort();
 		field_2_attributes          = in.readShort();
@@ -490,4 +508,9 @@ public final class FontRecord extends St
     public boolean equals(Object o) {
         return (o instanceof FontRecord) && sameProperties((FontRecord) o);
     }
+
+	@Override
+	public FontRecord copy() {
+		return new FontRecord(this);
+	}
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FooterRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FooterRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FooterRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FooterRecord.java Sun Dec 22 21:44:45 2019
@@ -17,18 +17,22 @@
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.util.Removal;
+
 /**
- * Title:        Footer Record (0x0015)<p>
- * Description:  Specifies the footer for a sheet<p>
- * REFERENCE:  PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Specifies the footer for a sheet
  */
-public final class FooterRecord extends HeaderFooterBase implements Cloneable {
-	public final static short sid = 0x0015;
+public final class FooterRecord extends HeaderFooterBase {
+	public static final short sid = 0x0015;
 
 	public FooterRecord(String text) {
 		super(text);
 	}
 
+	public FooterRecord(FooterRecord other) {
+		super(other);
+	}
+
 	public FooterRecord(RecordInputStream in) {
 		super(in);
 	}
@@ -47,7 +51,15 @@ public final class FooterRecord extends
 	}
 
 	@Override
+	@SuppressWarnings("squid:S2975")
+	@Deprecated
+	@Removal(version = "5.0.0")
 	public FooterRecord clone() {
-		return new FooterRecord(getText());
+		return copy();
+	}
+
+	@Override
+	public FooterRecord copy() {
+		return new FooterRecord(this);
 	}
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FormatRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FormatRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FormatRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FormatRecord.java Sun Dec 22 21:44:45 2019
@@ -22,30 +22,29 @@ import org.apache.poi.util.LittleEndianC
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Removal;
 import org.apache.poi.util.StringUtil;
 
 /**
- * Title:        Format Record (0x041E)<p>
- * Description:  describes a number format -- those goofy strings like $(#,###)<p>
- *
- * REFERENCE:  PG 317 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Describes a number format -- those goofy strings like $(#,###)
  */
-public final class FormatRecord extends StandardRecord implements Cloneable {
+public final class FormatRecord extends StandardRecord {
 
     private static final POILogger logger = POILogFactory.getLogger(FormatRecord.class);
 
-    public final static short sid = 0x041E;
+    public static final short sid = 0x041E;
 
     private final int field_1_index_code;
     private final boolean field_3_hasMultibyte;
     private final String field_4_formatstring;
 
     private FormatRecord(FormatRecord other) {
+        super(other);
         field_1_index_code = other.field_1_index_code;
         field_3_hasMultibyte = other.field_3_hasMultibyte;
         field_4_formatstring = other.field_4_formatstring;
     }
-    
+
     public FormatRecord(int indexCode, String fs) {
         field_1_index_code = indexCode;
         field_4_formatstring = fs;
@@ -114,9 +113,17 @@ public final class FormatRecord extends
     public short getSid() {
         return sid;
     }
-    
+
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public FormatRecord clone() {
+        return copy();
+    }
+
+    @Override
+    public FormatRecord copy() {
         return new FormatRecord(this);
     }
 

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FormulaRecord.java Sun Dec 22 21:44:45 2019
@@ -18,168 +18,28 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.ss.formula.Formula;
-import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.ss.usermodel.CellType;
-import org.apache.poi.util.*;
+import org.apache.poi.util.BitField;
+import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
  * Formula Record (0x0006).
- * REFERENCE:  PG 317/444 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
- * @author Jason Height (jheight at chariot dot net dot au)
  */
-public final class FormulaRecord extends CellRecord implements Cloneable {
+public final class FormulaRecord extends CellRecord {
 
-	public static final short sid = 0x0006;   // docs say 406...because of a bug Microsoft support site article #Q184647)
-	private static int FIXED_SIZE = 14; // double + short + int
+	// docs say 406...because of a bug Microsoft support site article #Q184647)
+	public static final short sid = 0x0006;
+	// double + short + int
+	private static final int FIXED_SIZE = 14;
 
 	private static final BitField alwaysCalc = BitFieldFactory.getInstance(0x0001);
 	private static final BitField calcOnLoad = BitFieldFactory.getInstance(0x0002);
 	private static final BitField sharedFormula = BitFieldFactory.getInstance(0x0008);
 
-	/**
-	 * Manages the cached formula result values of other types besides numeric.
-	 * Excel encodes the same 8 bytes that would be field_4_value with various NaN
-	 * values that are decoded/encoded by this class. 
-	 */
-	static final class SpecialCachedValue {
-		/** deliberately chosen by Excel in order to encode other values within Double NaNs */
-		private static final long BIT_MARKER = 0xFFFF000000000000L;
-		private static final int VARIABLE_DATA_LENGTH = 6;
-		private static final int DATA_INDEX = 2;
-
-		// FIXME: can these be merged with {@link CellType}?
-		// are the numbers specific to the HSSF formula record format or just a poor-man's enum?
-		public static final int STRING = 0;
-		public static final int BOOLEAN = 1;
-		public static final int ERROR_CODE = 2;
-		public static final int EMPTY = 3;
-
-		private final byte[] _variableData;
-
-		private SpecialCachedValue(byte[] data) {
-			_variableData = data;
-		}
-
-		public int getTypeCode() {
-			return _variableData[0];
-		}
-
-		/**
-		 * @return <code>null</code> if the double value encoded by <tt>valueLongBits</tt> 
-		 * is a normal (non NaN) double value.
-		 */
-		public static SpecialCachedValue create(long valueLongBits) {
-			if ((BIT_MARKER & valueLongBits) != BIT_MARKER) {
-				return null;
-			}
-
-			byte[] result = new byte[VARIABLE_DATA_LENGTH];
-			long x = valueLongBits;
-			for (int i=0; i<VARIABLE_DATA_LENGTH; i++) {
-				result[i] = (byte) x;
-				x >>= 8;
-			}
-			switch (result[0]) {
-				case STRING:
-				case BOOLEAN:
-				case ERROR_CODE:
-				case EMPTY:
-					break;
-				default:
-					throw new org.apache.poi.util.RecordFormatException("Bad special value code (" + result[0] + ")");
-			}
-			return new SpecialCachedValue(result);
-		}
-
-		public void serialize(LittleEndianOutput out) {
-			out.write(_variableData);
-			out.writeShort(0xFFFF);
-		}
-
-		public String formatDebugString() {
-			return formatValue() + ' ' + HexDump.toHex(_variableData);
-		}
-
-		private String formatValue() {
-			int typeCode = getTypeCode();
-			switch (typeCode) {
-				case STRING:
-					return "<string>";
-				case BOOLEAN:
-					return getDataValue() == 0 ? "FALSE" : "TRUE";
-				case ERROR_CODE:
-					return ErrorEval.getText(getDataValue());
-				case EMPTY:
-					return "<empty>";
-			}
-			return "#error(type=" + typeCode + ")#";
-		}
-
-		private int getDataValue() {
-			return _variableData[DATA_INDEX];
-		}
-
-		public static SpecialCachedValue createCachedEmptyValue() {
-			return create(EMPTY, 0);
-		}
-
-		public static SpecialCachedValue createForString() {
-			return create(STRING, 0);
-		}
-
-		public static SpecialCachedValue createCachedBoolean(boolean b) {
-			return create(BOOLEAN, b ? 1 : 0);
-		}
-
-		public static SpecialCachedValue createCachedErrorCode(int errorCode) {
-			return create(ERROR_CODE, errorCode);
-		}
-
-		private static SpecialCachedValue create(int code, int data) {
-			byte[] vd = {
-					(byte) code,
-					0,
-					(byte) data,
-					0,
-					0,
-					0,
-			};
-			return new SpecialCachedValue(vd);
-		}
-
-		@Override
-        public String toString() {
-			return getClass().getName() + '[' + formatValue() + ']';
-		}
-
-		public int getValueType() {
-			int typeCode = getTypeCode();
-			switch (typeCode) {
-				case STRING:	 return CellType.STRING.getCode();
-				case BOOLEAN:	return CellType.BOOLEAN.getCode();
-				case ERROR_CODE: return CellType.ERROR.getCode();
-				case EMPTY:	  return CellType.STRING.getCode(); // is this correct?
-			}
-			throw new IllegalStateException("Unexpected type id (" + typeCode + ")");
-		}
-
-		public boolean getBooleanValue() {
-			if (getTypeCode() != BOOLEAN) {
-				throw new IllegalStateException("Not a boolean cached value - " + formatValue());
-			}
-			return getDataValue() != 0;
-		}
-
-		public int getErrorValue() {
-			if (getTypeCode() != ERROR_CODE) {
-				throw new IllegalStateException("Not an error cached value - " + formatValue());
-			}
-			return getDataValue();
-		}
-	}
-
 	private double field_4_value;
 	private short  field_5_options;
 	/**
@@ -193,19 +53,27 @@ public final class FormulaRecord extends
 	/**
 	 * Since the NaN support seems sketchy (different constants) we'll store and spit it out directly
 	 */
-	private SpecialCachedValue specialCachedValue;
+	private FormulaSpecialCachedValue specialCachedValue;
 
 	/** Creates new FormulaRecord */
-
 	public FormulaRecord() {
 		field_8_parsed_expr = Formula.create(Ptg.EMPTY_PTG_ARRAY);
 	}
 
+	public FormulaRecord(FormulaRecord other) {
+		super(other);
+		field_4_value = other.field_4_value;
+		field_5_options = other.field_5_options;
+		field_6_zero = other.field_6_zero;
+		field_8_parsed_expr = (other.field_8_parsed_expr == null) ? null : new Formula(other.field_8_parsed_expr);
+		specialCachedValue = (other.specialCachedValue == null) ? null : new FormulaSpecialCachedValue(other.specialCachedValue);
+	}
+
 	public FormulaRecord(RecordInputStream ris) {
 		super(ris);
 		long valueLongBits  = ris.readLong();
 		field_5_options = ris.readShort();
-		specialCachedValue = SpecialCachedValue.create(valueLongBits);
+		specialCachedValue = FormulaSpecialCachedValue.create(valueLongBits);
 		if (specialCachedValue == null) {
 			field_4_value = Double.longBitsToDouble(valueLongBits);
 		}
@@ -228,16 +96,16 @@ public final class FormulaRecord extends
 	}
 
 	public void setCachedResultTypeEmptyString() {
-		specialCachedValue = SpecialCachedValue.createCachedEmptyValue();
+		specialCachedValue = FormulaSpecialCachedValue.createCachedEmptyValue();
 	}
 	public void setCachedResultTypeString() {
-		specialCachedValue = SpecialCachedValue.createForString();
+		specialCachedValue = FormulaSpecialCachedValue.createForString();
 	}
 	public void setCachedResultErrorCode(int errorCode) {
-		specialCachedValue = SpecialCachedValue.createCachedErrorCode(errorCode);
+		specialCachedValue = FormulaSpecialCachedValue.createCachedErrorCode(errorCode);
 	}
 	public void setCachedResultBoolean(boolean value) {
-		specialCachedValue = SpecialCachedValue.createCachedBoolean(value);
+		specialCachedValue = FormulaSpecialCachedValue.createCachedBoolean(value);
 	}
 	/**
 	 * @return <code>true</code> if this {@link FormulaRecord} is followed by a
@@ -246,7 +114,7 @@ public final class FormulaRecord extends
 	 */
 	public boolean hasCachedResultString() {
 		return specialCachedValue != null &&
-				specialCachedValue.getTypeCode() == SpecialCachedValue.STRING;
+				specialCachedValue.getTypeCode() == FormulaSpecialCachedValue.STRING;
 	}
 
 	public int getCachedResultType() {
@@ -353,12 +221,12 @@ public final class FormulaRecord extends
 		out.writeInt(field_6_zero); // may as well write original data back so as to minimise differences from original
 		field_8_parsed_expr.serialize(out);
 	}
-	
+
 	@Override
 	protected String getRecordName() {
 		return "FORMULA";
 	}
-	
+
 	@Override
 	protected void appendValueText(StringBuilder sb) {
 		sb.append("  .value	 = ");
@@ -385,15 +253,16 @@ public final class FormulaRecord extends
 	}
 
 	@Override
-    public FormulaRecord clone() {
-		FormulaRecord rec = new FormulaRecord();
-		copyBaseFields(rec);
-		rec.field_4_value = field_4_value;
-		rec.field_5_options = field_5_options;
-		rec.field_6_zero = field_6_zero;
-		rec.field_8_parsed_expr = field_8_parsed_expr;
-		rec.specialCachedValue = specialCachedValue;
-		return rec;
+	@SuppressWarnings("squid:S2975")
+	@Deprecated
+	@Removal(version = "5.0.0")
+	public FormulaRecord clone() {
+		return copy();
+	}
+
+	@Override
+	public FormulaRecord copy() {
+		return new FormulaRecord(this);
 	}
 }
 

Added: poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java?rev=1871911&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java Sun Dec 22 21:44:45 2019
@@ -0,0 +1,167 @@
+/* ====================================================================
+   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.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.Internal;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * Manages the cached formula result values of other types besides numeric.
+ * Excel encodes the same 8 bytes that would be field_4_value with various NaN
+ * values that are decoded/encoded by this class.
+ */
+@Internal
+public final class FormulaSpecialCachedValue {
+    /** deliberately chosen by Excel in order to encode other values within Double NaNs */
+    private static final long BIT_MARKER = 0xFFFF000000000000L;
+    private static final int VARIABLE_DATA_LENGTH = 6;
+    private static final int DATA_INDEX = 2;
+
+    // FIXME: can these be merged with {@link CellType}?
+    // are the numbers specific to the HSSF formula record format or just a poor-man's enum?
+    public static final int STRING = 0;
+    public static final int BOOLEAN = 1;
+    public static final int ERROR_CODE = 2;
+    public static final int EMPTY = 3;
+
+    private final byte[] _variableData;
+
+    FormulaSpecialCachedValue(FormulaSpecialCachedValue other) {
+        _variableData = (other._variableData == null) ? null : other._variableData.clone();
+    }
+
+    private FormulaSpecialCachedValue(byte[] data) {
+        _variableData = data;
+    }
+
+    public int getTypeCode() {
+        return _variableData[0];
+    }
+
+    /**
+     * @return <code>null</code> if the double value encoded by <tt>valueLongBits</tt>
+     * is a normal (non NaN) double value.
+     */
+    public static FormulaSpecialCachedValue create(long valueLongBits) {
+        if ((BIT_MARKER & valueLongBits) != BIT_MARKER) {
+            return null;
+        }
+
+        byte[] result = new byte[VARIABLE_DATA_LENGTH];
+        long x = valueLongBits;
+        for (int i=0; i<VARIABLE_DATA_LENGTH; i++) {
+            result[i] = (byte) x;
+            x >>= 8;
+        }
+        switch (result[0]) {
+            case STRING:
+            case BOOLEAN:
+            case ERROR_CODE:
+            case EMPTY:
+                break;
+            default:
+                throw new org.apache.poi.util.RecordFormatException("Bad special value code (" + result[0] + ")");
+        }
+        return new FormulaSpecialCachedValue(result);
+    }
+
+    public void serialize(LittleEndianOutput out) {
+        out.write(_variableData);
+        out.writeShort(0xFFFF);
+    }
+
+    public String formatDebugString() {
+        return formatValue() + ' ' + HexDump.toHex(_variableData);
+    }
+
+    private String formatValue() {
+        int typeCode = getTypeCode();
+        switch (typeCode) {
+            case STRING:
+                return "<string>";
+            case BOOLEAN:
+                return getDataValue() == 0 ? "FALSE" : "TRUE";
+            case ERROR_CODE:
+                return ErrorEval.getText(getDataValue());
+            case EMPTY:
+                return "<empty>";
+        }
+        return "#error(type=" + typeCode + ")#";
+    }
+
+    private int getDataValue() {
+        return _variableData[DATA_INDEX];
+    }
+
+    public static FormulaSpecialCachedValue createCachedEmptyValue() {
+        return create(EMPTY, 0);
+    }
+
+    public static FormulaSpecialCachedValue createForString() {
+        return create(STRING, 0);
+    }
+
+    public static FormulaSpecialCachedValue createCachedBoolean(boolean b) {
+        return create(BOOLEAN, b ? 1 : 0);
+    }
+
+    public static FormulaSpecialCachedValue createCachedErrorCode(int errorCode) {
+        return create(ERROR_CODE, errorCode);
+    }
+
+    private static FormulaSpecialCachedValue create(int code, int data) {
+        byte[] vd = { (byte) code, 0, (byte) data, 0, 0, 0, };
+        return new FormulaSpecialCachedValue(vd);
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName() + '[' + formatValue() + ']';
+    }
+
+    public int getValueType() {
+        int typeCode = getTypeCode();
+        switch (typeCode) {
+            case EMPTY: // is this correct?
+            case STRING:
+                return CellType.STRING.getCode();
+            case BOOLEAN:
+                return CellType.BOOLEAN.getCode();
+            case ERROR_CODE:
+                return CellType.ERROR.getCode();
+        }
+        throw new IllegalStateException("Unexpected type id (" + typeCode + ")");
+    }
+
+    public boolean getBooleanValue() {
+        if (getTypeCode() != BOOLEAN) {
+            throw new IllegalStateException("Not a boolean cached value - " + formatValue());
+        }
+        return getDataValue() != 0;
+    }
+
+    public int getErrorValue() {
+        if (getTypeCode() != ERROR_CODE) {
+            throw new IllegalStateException("Not an error cached value - " + formatValue());
+        }
+        return getDataValue();
+    }
+}

Propchange: poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java Sun Dec 22 21:44:45 2019
@@ -22,28 +22,31 @@ import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 
 
 /**
  * This structure appears as part of an Obj record that represents a checkbox or radio button.
- *
- * @author Yegor Kozlov
  */
-public final class FtCblsSubRecord extends SubRecord implements Cloneable {
-    public final static short sid = 0x0C;
+public final class FtCblsSubRecord extends SubRecord {
+    public static final short sid = 0x0C;
     private static final int ENCODED_SIZE = 20;
 
-    private byte[] reserved;
+    private final byte[] reserved;
 
     /**
      * Construct a new <code>FtCblsSubRecord</code> and
      * fill its data with the default values
      */
-    public FtCblsSubRecord()
-    {
+    public FtCblsSubRecord() {
         reserved = new byte[ENCODED_SIZE];
     }
 
+    public FtCblsSubRecord(FtCblsSubRecord other) {
+        super(other);
+        reserved = other.reserved.clone();
+    }
+
     public FtCblsSubRecord(LittleEndianInput in, int size) {
         if (size != ENCODED_SIZE) {
             throw new RecordFormatException("Unexpected size (" + size + ")");
@@ -93,12 +96,16 @@ public final class FtCblsSubRecord exten
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public FtCblsSubRecord clone() {
-        FtCblsSubRecord rec = new FtCblsSubRecord();
-        byte[] recdata = new byte[reserved.length];
-        System.arraycopy(reserved, 0, recdata, 0, recdata.length);
-        rec.reserved = recdata;
-        return rec;
+        return copy();
+    }
+
+    @Override
+    public FtCblsSubRecord copy() {
+        return new FtCblsSubRecord(this);
     }
 
 }
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java Sun Dec 22 21:44:45 2019
@@ -21,15 +21,16 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 
 
 /**
  * The FtCf structure specifies the clipboard format of the picture-type Obj record containing this FtCf.
  */
-public final class FtCfSubRecord extends SubRecord implements Cloneable {
-    public final static short sid = 0x07;
-    public final static short length = 0x02;
-    
+public final class FtCfSubRecord extends SubRecord {
+    public static final short sid = 0x07;
+    public static final short length = 0x02;
+
     /**
      * Specifies the format of the picture is an enhanced metafile.
      */
@@ -39,20 +40,24 @@ public final class FtCfSubRecord extends
      * Specifies the format of the picture is a bitmap.
      */
     public static final short BITMAP_BIT      = (short)0x0009;
-    
+
     /**
      * Specifies the picture is in an unspecified format that is
      * neither and enhanced metafile nor a bitmap.
      */
     public static final short UNSPECIFIED_BIT = (short)0xFFFF;
-    
+
     private short flags;
 
     /**
      * Construct a new <code>FtPioGrbitSubRecord</code> and
      * fill its data with the default values
      */
-    public FtCfSubRecord() {
+    public FtCfSubRecord() {}
+
+    public FtCfSubRecord(FtCfSubRecord other) {
+        super(other);
+        flags = other.flags;
     }
 
     public FtCfSubRecord(LittleEndianInput in, int size) {
@@ -99,10 +104,16 @@ public final class FtCfSubRecord extends
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public FtCfSubRecord clone() {
-        FtCfSubRecord rec = new FtCfSubRecord();
-        rec.flags = this.flags;
-        return rec;
+        return copy();
+    }
+
+    @Override
+    public FtCfSubRecord copy() {
+        return new FtCfSubRecord(this);
     }
 
  public short getFlags() {

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java Sun Dec 22 21:44:45 2019
@@ -21,27 +21,28 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 
 
 /**
  * This structure appears as part of an Obj record that represents image display properties.
  */
-public final class FtPioGrbitSubRecord extends SubRecord implements Cloneable {
-    public final static short sid = 0x08;
-    public final static short length = 0x02;
-    
+public final class FtPioGrbitSubRecord extends SubRecord {
+    public static final short sid = 0x08;
+    public static final short length = 0x02;
+
     /**
-     * A bit that specifies whether the picture's aspect ratio is preserved when rendered in 
+     * A bit that specifies whether the picture's aspect ratio is preserved when rendered in
      * different views (Normal view, Page Break Preview view, Page Layout view and printing).
      */
     public static final int AUTO_PICT_BIT    = 1 << 0;
 
     /**
-     * A bit that specifies whether the pictFmla field of the Obj record that contains 
+     * A bit that specifies whether the pictFmla field of the Obj record that contains
      * this FtPioGrbit specifies a DDE reference.
      */
     public static final int DDE_BIT          = 1 << 1;
-    
+
     /**
      * A bit that specifies whether this object is expected to be updated on print to
      * reflect the values in the cell associated with the object.
@@ -52,44 +53,48 @@ public final class FtPioGrbitSubRecord e
      * A bit that specifies whether the picture is displayed as an icon.
      */
     public static final int ICON_BIT         = 1 << 3;
-    
+
     /**
      * A bit that specifies whether this object is an ActiveX control.
      * It MUST NOT be the case that both fCtl and fDde are equal to 1.
      */
     public static final int CTL_BIT          = 1 << 4;
-    
+
     /**
      * A bit that specifies whether the object data are stored in an
      * embedding storage (= 0) or in the controls stream (ctls) (= 1).
      */
     public static final int PRSTM_BIT        = 1 << 5;
-    
+
     /**
      * A bit that specifies whether this is a camera picture.
      */
     public static final int CAMERA_BIT       = 1 << 7;
-    
+
     /**
      * A bit that specifies whether this picture's size has been explicitly set.
      * 0 = picture size has been explicitly set, 1 = has not been set
      */
     public static final int DEFAULT_SIZE_BIT = 1 << 8;
-    
+
     /**
      * A bit that specifies whether the OLE server for the object is called
      * to load the object's data automatically when the parent workbook is opened.
      */
     public static final int AUTO_LOAD_BIT    = 1 << 9;
 
-    
+
     private short flags;
 
     /**
      * Construct a new <code>FtPioGrbitSubRecord</code> and
      * fill its data with the default values
      */
-    public FtPioGrbitSubRecord() {
+    public FtPioGrbitSubRecord() {}
+
+    public FtPioGrbitSubRecord(FtPioGrbitSubRecord other) {
+        super(other);
+        flags = other.flags;
     }
 
     public FtPioGrbitSubRecord(LittleEndianInput in, int size) {
@@ -110,12 +115,12 @@ public final class FtPioGrbitSubRecord e
         } else {
             flags &= (0xFFFF ^ bitmask);
         }
-    }    
-    
+    }
+
     public boolean getFlagByBit(int bitmask) {
         return ((flags & bitmask) != 0);
     }
-    
+
     /**
      * Convert this record to string.
      * Used by BiffViewer and other utilities.
@@ -153,10 +158,16 @@ public final class FtPioGrbitSubRecord e
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public FtPioGrbitSubRecord clone() {
-        FtPioGrbitSubRecord rec = new FtPioGrbitSubRecord();
-        rec.flags = this.flags;
-        return rec;
+        return copy();
+    }
+
+    @Override
+    public FtPioGrbitSubRecord copy() {
+        return new FtPioGrbitSubRecord(this);
     }
 
  public short getFlags() {

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java Sun Dec 22 21:44:45 2019
@@ -18,28 +18,25 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Gridset Record.<P>
- * Description:  flag denoting whether the user specified that gridlines are used when
- *               printing.<P>
- * REFERENCE:  PG 320 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)
- * @author Jason Height (jheight at chariot dot net dot au)
+ * Flag denoting whether the user specified that gridlines are used when printing.
  *
  * @version 2.0-pre
  */
-public final class GridsetRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x82;
+public final class GridsetRecord extends StandardRecord {
+    public static final short sid = 0x82;
     public short              field_1_gridset_flag;
 
-    public GridsetRecord() {
+    public GridsetRecord() {}
+
+    public GridsetRecord(GridsetRecord other) {
+        super(other);
+        field_1_gridset_flag = other.field_1_gridset_flag;
     }
 
-    public GridsetRecord(RecordInputStream in)
-    {
+    public GridsetRecord(RecordInputStream in) {
         field_1_gridset_flag = in.readShort();
     }
 
@@ -87,9 +84,15 @@ public final class GridsetRecord extends
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public GridsetRecord clone() {
-      GridsetRecord rec = new GridsetRecord();
-      rec.field_1_gridset_flag = field_1_gridset_flag;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public GridsetRecord copy() {
+        return new GridsetRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java Sun Dec 22 21:44:45 2019
@@ -21,13 +21,14 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
  * ftGmo (0x0006)<p>
  * The group marker record is used as a position holder for groups.
  */
-public final class GroupMarkerSubRecord extends SubRecord implements Cloneable {
-    public final static short sid = 0x0006;
+public final class GroupMarkerSubRecord extends SubRecord {
+    public static final short sid = 0x0006;
     //arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 100_000;
 
@@ -41,6 +42,11 @@ public final class GroupMarkerSubRecord
         reserved = EMPTY_BYTE_ARRAY;
     }
 
+    public GroupMarkerSubRecord(GroupMarkerSubRecord other) {
+        super(other);
+        reserved = other.reserved.clone();
+    }
+
     public GroupMarkerSubRecord(LittleEndianInput in, int size) {
         byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
         in.readFully(buf);
@@ -74,10 +80,15 @@ public final class GroupMarkerSubRecord
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public GroupMarkerSubRecord clone() {
-        GroupMarkerSubRecord rec = new GroupMarkerSubRecord();
-        rec.reserved = new byte[reserved.length];
-        System.arraycopy(reserved, 0, rec.reserved, 0, reserved.length);
-        return rec;
+        return copy();
+    }
+
+    @Override
+    public GroupMarkerSubRecord copy() {
+        return new GroupMarkerSubRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java Sun Dec 22 21:44:45 2019
@@ -15,34 +15,41 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Guts Record <P>
- * Description:  Row/column gutter sizes <P>
- * REFERENCE:  PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
- * @author Jason Height (jheight at chariot dot net dot au)
+ * Row/column gutter sizes
+ *
  * @version 2.0-pre
  */
 
-public final class GutsRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x80;
-    private short             field_1_left_row_gutter;   // size of the row gutter to the left of the rows
-    private short             field_2_top_col_gutter;    // size of the column gutter above the columns
-    private short             field_3_row_level_max;     // maximum outline level for row gutters
-    private short             field_4_col_level_max;     // maximum outline level for column gutters
-
-    public GutsRecord()
-    {
+public final class GutsRecord extends StandardRecord {
+    public static final short sid = 0x80;
+    /** size of the row gutter to the left of the rows */
+    private short field_1_left_row_gutter;
+    /** size of the column gutter above the columns */
+    private short field_2_top_col_gutter;
+    /** maximum outline level for row gutters */
+    private short field_3_row_level_max;
+    /** maximum outline level for column gutters */
+    private short field_4_col_level_max;
+
+    public GutsRecord() {}
+
+    public GutsRecord(GutsRecord other) {
+        super(other);
+        field_1_left_row_gutter = other.field_1_left_row_gutter;
+        field_2_top_col_gutter  = other.field_2_top_col_gutter;
+        field_3_row_level_max   = other.field_3_row_level_max;
+        field_4_col_level_max   = other.field_4_col_level_max;
     }
 
-    public GutsRecord(RecordInputStream in)
-    {
+    public GutsRecord(RecordInputStream in) {
         field_1_left_row_gutter = in.readShort();
         field_2_top_col_gutter  = in.readShort();
         field_3_row_level_max   = in.readShort();
@@ -171,12 +178,15 @@ public final class GutsRecord extends St
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public GutsRecord clone() {
-      GutsRecord rec = new GutsRecord();
-      rec.field_1_left_row_gutter = field_1_left_row_gutter;
-      rec.field_2_top_col_gutter = field_2_top_col_gutter;
-      rec.field_3_row_level_max = field_3_row_level_max;
-      rec.field_4_col_level_max = field_4_col_level_max;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public GutsRecord copy() {
+      return new GutsRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java Sun Dec 22 21:44:45 2019
@@ -17,24 +17,25 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        HCenter record (0x0083)<P>
- * Description:  whether to center between horizontal margins<P>
- * REFERENCE:  PG 320 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
- * @author Jason Height (jheight at chariot dot net dot au)
+ * Whether to center between horizontal margins
+ *
  * @version 2.0-pre
  */
-public final class HCenterRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x0083;
-    private short             field_1_hcenter;
+public final class HCenterRecord extends StandardRecord {
+    public static final short sid = 0x0083;
+    private short field_1_hcenter;
 
-    public HCenterRecord() {
+    public HCenterRecord() {}
+
+    public HCenterRecord(HCenterRecord other) {
+        super(other);
+        field_1_hcenter = other.field_1_hcenter;
     }
 
-    public HCenterRecord(RecordInputStream in)
-    {
+    public HCenterRecord(RecordInputStream in) {
         field_1_hcenter = in.readShort();
     }
 
@@ -43,11 +44,7 @@ public final class HCenterRecord extends
      * @param hc  center - t/f
      */
     public void setHCenter(boolean hc) {
-        if (hc) {
-            field_1_hcenter = 1;
-        } else {
-            field_1_hcenter = 0;
-        }
+        field_1_hcenter = (short)(hc ? 1 : 0);
     }
 
     /**
@@ -80,9 +77,15 @@ public final class HCenterRecord extends
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public HCenterRecord clone() {
-      HCenterRecord rec = new HCenterRecord();
-      rec.field_1_hcenter = field_1_hcenter;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public HCenterRecord copy() {
+      return new HCenterRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java Sun Dec 22 21:44:45 2019
@@ -22,8 +22,6 @@ import org.apache.poi.util.StringUtil;
 
 /**
  * Common header/footer base class
- *
- * @author Josh Micich
  */
 public abstract class HeaderFooterBase extends StandardRecord {
 	private boolean field_2_hasMultibyte;
@@ -33,6 +31,12 @@ public abstract class HeaderFooterBase e
 		setText(text);
 	}
 
+	protected HeaderFooterBase(HeaderFooterBase other) {
+		super(other);
+		field_2_hasMultibyte = other.field_2_hasMultibyte;
+		field_3_text = other.field_3_text;
+	}
+
 	protected HeaderFooterBase(RecordInputStream in) {
 		if (in.remaining() > 0) {
 			int field_1_footer_len = in.readShort();
@@ -107,4 +111,7 @@ public abstract class HeaderFooterBase e
 		}
 		return 3 + getTextLength() * (field_2_hasMultibyte ? 2 : 1);
 	}
+
+	@Override
+	public abstract HeaderFooterBase copy();
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java Sun Dec 22 21:44:45 2019
@@ -17,28 +17,31 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
-import org.apache.poi.util.LittleEndianOutput;
-
 import java.util.Arrays;
 import java.util.Locale;
 
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
+
 /**
  * The HEADERFOOTER record stores information added in Office Excel 2007 for headers/footers.
- *
- * @author Yegor Kozlov
  */
-public final class HeaderFooterRecord extends StandardRecord implements Cloneable {
-
+public final class HeaderFooterRecord extends StandardRecord {
+    public static final short sid = 0x089C;
     private static final byte[] BLANK_GUID = new byte[16];
 
-    public final static short sid = 0x089C;
 	private byte[] _rawData;
 
     public HeaderFooterRecord(byte[] data) {
         _rawData = data;
     }
 
+    public HeaderFooterRecord(HeaderFooterRecord other) {
+        super(other);
+        _rawData = (other._rawData == null) ? null : other._rawData.clone();
+    }
+
 	/**
 	 * construct a HeaderFooterRecord record.  No fields are interpreted and the record will
 	 * be serialized in its original form more or less
@@ -58,7 +61,7 @@ public final class HeaderFooterRecord ex
 	protected int getDataSize() {
 		return _rawData.length;
 	}
-    
+
     public short getSid()
     {
         return sid;
@@ -79,7 +82,7 @@ public final class HeaderFooterRecord ex
     }
 
     /**
-     * @return whether this record belongs to the current sheet 
+     * @return whether this record belongs to the current sheet
      */
     public boolean isCurrentSheet(){
         return Arrays.equals(getGuid(), BLANK_GUID);
@@ -96,10 +99,17 @@ public final class HeaderFooterRecord ex
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public HeaderFooterRecord clone() {
-        //HACK: do a "cheat" clone, see Record.java for more information
-        return (HeaderFooterRecord)cloneViaReserialise();
+        return copy();
     }
-    
- 
+
+    @Override
+    public HeaderFooterRecord copy() {
+        return new HeaderFooterRecord(this);
+    }
+
+
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java Sun Dec 22 21:44:45 2019
@@ -17,21 +17,22 @@
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.util.Removal;
+
 /**
- * Title:        Header Record<P>
- * Description:  Specifies a header for a sheet<P>
- * REFERENCE:  PG 321 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
- * @author Shawn Laubach (slaubach at apache dot org) Modified 3/14/02
- * @author Jason Height (jheight at chariot dot net dot au)
+ * Specifies a header for a sheet
  */
-public final class HeaderRecord extends HeaderFooterBase implements Cloneable {
-	public final static short sid = 0x0014;
+public final class HeaderRecord extends HeaderFooterBase {
+	public static final short sid = 0x0014;
 
 	public HeaderRecord(String text) {
 		super(text);
 	}
 
+	public HeaderRecord(HeaderRecord other) {
+		super(other);
+	}
+
 	public HeaderRecord(RecordInputStream in) {
 		super(in);
 	}
@@ -50,7 +51,15 @@ public final class HeaderRecord extends
 	}
 
 	@Override
+	@SuppressWarnings("squid:S2975")
+	@Deprecated
+	@Removal(version = "5.0.0")
 	public HeaderRecord clone() {
-		return new HeaderRecord(getText());
+		return copy();
+	}
+
+	@Override
+	public HeaderRecord copy() {
+		return new HeaderRecord(this);
 	}
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java Sun Dec 22 21:44:45 2019
@@ -15,35 +15,33 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title:        Hide Object Record<P>
- * Description:  flag defines whether to hide placeholders and object<P>
- * REFERENCE:  PG 321 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
+ * Flag defines whether to hide placeholders and object
+ *
  * @version 2.0-pre
  */
+public final class HideObjRecord extends StandardRecord {
+    public static final short sid               = 0x8d;
+    public static final short HIDE_ALL          = 2;
+    public static final short SHOW_PLACEHOLDERS = 1;
+    public static final short SHOW_ALL          = 0;
 
-public final class HideObjRecord
-    extends StandardRecord
-{
-    public final static short sid               = 0x8d;
-    public final static short HIDE_ALL          = 2;
-    public final static short SHOW_PLACEHOLDERS = 1;
-    public final static short SHOW_ALL          = 0;
-    private short             field_1_hide_obj;
+    private short field_1_hide_obj;
 
-    public HideObjRecord()
-    {
+    public HideObjRecord() {}
+
+    public HideObjRecord(HideObjRecord other) {
+        super(other);
+        field_1_hide_obj = other.field_1_hide_obj;
     }
 
-    public HideObjRecord(RecordInputStream in)
-    {
+    public HideObjRecord(RecordInputStream in) {
         field_1_hide_obj = in.readShort();
     }
 
@@ -98,4 +96,9 @@ public final class HideObjRecord
     {
         return sid;
     }
+
+    @Override
+    public HideObjRecord copy() {
+        return new HideObjRecord(this);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java Sun Dec 22 21:44:45 2019
@@ -17,21 +17,24 @@
 
 package org.apache.poi.hssf.record;
 
-import java.util.Iterator;
+import org.apache.poi.util.Removal;
 
 /**
  * HorizontalPageBreak (0x001B) record that stores page breaks at rows
- * 
+ *
  * @see PageBreakRecord
  */
-public final class HorizontalPageBreakRecord extends PageBreakRecord implements Cloneable {
+public final class HorizontalPageBreakRecord extends PageBreakRecord {
 
 	public static final short sid = 0x001B;
 
 	/**
 	 * Creates an empty horizontal page break record
 	 */
-	public HorizontalPageBreakRecord() {
+	public HorizontalPageBreakRecord() {}
+
+	public HorizontalPageBreakRecord(HorizontalPageBreakRecord other) {
+		super(other);
 	}
 
 	/**
@@ -46,13 +49,15 @@ public final class HorizontalPageBreakRe
 	}
 
 	@Override
+	@SuppressWarnings("squid:S2975")
+	@Deprecated
+	@Removal(version = "5.0.0")
 	public PageBreakRecord clone() {
-		PageBreakRecord result = new HorizontalPageBreakRecord();
-		Iterator<Break> iterator = getBreaksIterator();
-		while (iterator.hasNext()) {
-			Break original = iterator.next();
-			result.addBreak(original.main, original.subFrom, original.subTo);
-		}
-		return result;
+		return copy();
+	}
+
+	@Override
+	public HorizontalPageBreakRecord copy() {
+		return new HorizontalPageBreakRecord(this);
 	}
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java Sun Dec 22 21:44:45 2019
@@ -27,6 +27,7 @@ import org.apache.poi.util.LittleEndianO
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 import org.apache.poi.util.StringUtil;
 
 /**
@@ -34,13 +35,14 @@ import org.apache.poi.util.StringUtil;
  *  from the Excel-97 format.
  * Supports only external links for now (eg http://)
  */
-public final class HyperlinkRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x01B8;
+public final class HyperlinkRecord extends StandardRecord {
+    public static final short sid = 0x01B8;
     private static POILogger logger = POILogFactory.getLogger(HyperlinkRecord.class);
     //arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 100_000;
 
 
+    // TODO: replace with ClassID
     static final class GUID {
         /*
          * this class is currently only used here, but could be moved to a
@@ -61,6 +63,13 @@ public final class HyperlinkRecord exten
          */
         private final long _d4;
 
+        public GUID(GUID other) {
+            _d1 = other._d1;
+            _d2 = other._d2;
+            _d3 = other._d3;
+            _d4 = other._d4;
+        }
+
         public GUID(LittleEndianInput in) {
             this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
         }
@@ -199,24 +208,24 @@ public final class HyperlinkRecord exten
         }
     }
 
-    /**
+    /*
      * Link flags
      */
-     static final int  HLINK_URL    = 0x01;  // File link or URL.
-     static final int  HLINK_ABS    = 0x02;  // Absolute path.
-     static final int  HLINK_LABEL  = 0x14;  // Has label/description.
+    static final int HLINK_URL    = 0x01;  // File link or URL.
+    static final int HLINK_ABS    = 0x02;  // Absolute path.
+    static final int HLINK_LABEL  = 0x14;  // Has label/description.
     /** Place in worksheet. If set, the {@link #_textMark} field will be present */
-     static final int  HLINK_PLACE  = 0x08;
+    static final int HLINK_PLACE  = 0x08;
     private static final int  HLINK_TARGET_FRAME  = 0x80;  // has 'target frame'
     private static final int  HLINK_UNC_PATH  = 0x100;  // has UNC path
 
-     final static GUID STD_MONIKER = GUID.parse("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B");
-     final static GUID URL_MONIKER = GUID.parse("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B");
-     final static GUID FILE_MONIKER = GUID.parse("00000303-0000-0000-C000-000000000046");
+    static final GUID STD_MONIKER = GUID.parse("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B");
+    static final GUID URL_MONIKER = GUID.parse("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B");
+    static final GUID FILE_MONIKER = GUID.parse("00000303-0000-0000-C000-000000000046");
     /** expected Tail of a URL link */
-    private final static byte[] URL_TAIL  = HexRead.readFromString("79 58 81 F4  3B 1D 7F 48   AF 2C 82 5D  C4 85 27 63   00 00 00 00  A5 AB 00 00"); 
+    private static final byte[] URL_TAIL  = HexRead.readFromString("79 58 81 F4  3B 1D 7F 48   AF 2C 82 5D  C4 85 27 63   00 00 00 00  A5 AB 00 00");
     /** expected Tail of a file link */
-    private final static byte[] FILE_TAIL = HexRead.readFromString("FF FF AD DE  00 00 00 00   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00");
+    private static final byte[] FILE_TAIL = HexRead.readFromString("FF FF AD DE  00 00 00 00   00 00 00 00  00 00 00 00   00 00 00 00  00 00 00 00");
 
     private static final int TAIL_SIZE = FILE_TAIL.length;
 
@@ -246,17 +255,31 @@ public final class HyperlinkRecord exten
      * This field is optional.  If present, the {@link #HLINK_PLACE} must be set.
      */
     private String _textMark;
-    
+
     private byte[] _uninterpretedTail;
 
     /**
      * Create a new hyperlink
      */
-    public HyperlinkRecord()
-    {
+    public HyperlinkRecord() {}
 
+
+    public HyperlinkRecord(HyperlinkRecord other) {
+        super(other);
+        _range = (other._range == null) ? null : other._range.copy();
+        _guid = (other._guid == null) ? null : new GUID(other._guid);
+        _fileOpts = other._fileOpts;
+        _linkOpts = other._linkOpts;
+        _label = other._label;
+        _targetFrame = other._targetFrame;
+        _moniker = (other._moniker == null) ? null : new GUID(other._moniker);
+        _shortFilename = other._shortFilename;
+        _address = other._address;
+        _textMark = other._textMark;
+        _uninterpretedTail = (other._uninterpretedTail == null) ? null : other._uninterpretedTail.clone();
     }
 
+
     /**
      * @return the 0-based column of the first cell that contains this hyperlink
      */
@@ -266,7 +289,7 @@ public final class HyperlinkRecord exten
 
     /**
      * Set the first column (zero-based) of the range that contains this hyperlink
-     * 
+     *
      * @param firstCol the first column (zero-based)
      */
     public void setFirstColumn(int firstCol) {
@@ -282,7 +305,7 @@ public final class HyperlinkRecord exten
 
     /**
      * Set the last column (zero-based) of the range that contains this hyperlink
-     * 
+     *
      * @param lastCol the last column (zero-based)
      */
     public void setLastColumn(int lastCol) {
@@ -298,7 +321,7 @@ public final class HyperlinkRecord exten
 
     /**
      * Set the first row (zero-based) of the range that contains this hyperlink
-     * 
+     *
      * @param firstRow the first row (zero-based)
      */
     public void setFirstRow(int firstRow) {
@@ -314,7 +337,7 @@ public final class HyperlinkRecord exten
 
     /**
      * Set the last row (zero-based) of the range that contains this hyperlink
-     * 
+     *
      * @param lastRow the last row (zero-based)
      */
     public void setLastRow(int lastRow) {
@@ -423,7 +446,7 @@ public final class HyperlinkRecord exten
     /**
      * Link options. Must be a combination of HLINK_* constants.
      * For testing only
-     * 
+     *
      * @return Link options
      */
     int getLinkOptions(){
@@ -541,7 +564,7 @@ public final class HyperlinkRecord exten
         }
 
         if (in.remaining() > 0) {
-           logger.log(POILogger.WARN, 
+           logger.log(POILogger.WARN,
                  "Hyperlink data remains: " + in.remaining() +
                  " : " +HexDump.toHex(in.readRemainder())
            );
@@ -699,31 +722,31 @@ public final class HyperlinkRecord exten
 
     /**
      * Based on the link options, is this a url?
-     * 
+     *
      * @return true, if this is a url link
      */
     public boolean isUrlLink() {
-       return (_linkOpts & HLINK_URL) > 0 
+       return (_linkOpts & HLINK_URL) > 0
            && (_linkOpts & HLINK_ABS) > 0;
     }
     /**
      * Based on the link options, is this a file?
-     * 
+     *
      * @return true, if this is a file link
      */
     public boolean isFileLink() {
-       return (_linkOpts & HLINK_URL) > 0 
+       return (_linkOpts & HLINK_URL) > 0
            && (_linkOpts & HLINK_ABS) == 0;
     }
     /**
      * Based on the link options, is this a document?
-     * 
+     *
      * @return true, if this is a docment link
      */
     public boolean isDocumentLink() {
-       return (_linkOpts & HLINK_PLACE) > 0; 
+       return (_linkOpts & HLINK_PLACE) > 0;
     }
-    
+
     /**
      * Initialize a new url link
      */
@@ -766,19 +789,15 @@ public final class HyperlinkRecord exten
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public HyperlinkRecord clone() {
-        HyperlinkRecord rec = new HyperlinkRecord();
-        rec._range = _range.copy();
-        rec._guid = _guid;
-        rec._linkOpts = _linkOpts;
-        rec._fileOpts = _fileOpts;
-        rec._label = _label;
-        rec._address = _address;
-        rec._moniker = _moniker;
-        rec._shortFilename = _shortFilename;
-        rec._targetFrame = _targetFrame;
-        rec._textMark = _textMark;
-        rec._uninterpretedTail = _uninterpretedTail;
-        return rec;
+        return copy();
+    }
+
+    @Override
+    public HyperlinkRecord copy() {
+        return new HyperlinkRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java Sun Dec 22 21:44:45 2019
@@ -20,27 +20,29 @@ package org.apache.poi.hssf.record;
 import org.apache.poi.util.IntList;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Index Record (0x020B)<p>
- * Description:  Occurs right after BOF, tells you where the DBCELL records are for a sheet
- *               Important for locating cells<p>
- *               
- * REFERENCE:  PG 323 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Occurs right after BOF, tells you where the DBCELL records are for a sheet Important for locating cells
  */
-public final class IndexRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x020B;
+public final class IndexRecord extends StandardRecord {
+    public static final short sid = 0x020B;
     private int                field_2_first_row;       // first row on the sheet
     private int                field_3_last_row_add1;   // last row
     private int                field_4_zero;            // supposed to be zero
     private IntList            field_5_dbcells;         // array of offsets to DBCELL records
 
-    public IndexRecord()
-    {
+    public IndexRecord() {}
+
+    public IndexRecord(IndexRecord other) {
+        super(other);
+        field_2_first_row = other.field_2_first_row;
+        field_3_last_row_add1 = other.field_3_last_row_add1;
+        field_4_zero = other.field_4_zero;
+        field_5_dbcells = (other.field_5_dbcells == null) ? null : new IntList(other.field_5_dbcells);
     }
 
-    public IndexRecord(RecordInputStream in)
-    {
+    public IndexRecord(RecordInputStream in) {
         int field_1_zero          = in.readInt();
         if (field_1_zero != 0) {
         	throw new RecordFormatException("Expected zero for field 1 but got " + field_1_zero);
@@ -48,7 +50,7 @@ public final class IndexRecord extends S
         field_2_first_row     = in.readInt();
         field_3_last_row_add1 = in.readInt();
         field_4_zero      = in.readInt();
-        
+
         int nCells = in.remaining() / 4;
         field_5_dbcells = new IntList(nCells);
         for(int i=0; i<nCells; i++) {
@@ -139,14 +141,14 @@ public final class IndexRecord extends S
         return 16 // 4 ints
         	+ getNumDbcells() * 4;
     }
-    
-    /** 
+
+    /**
      * @param blockCount the number of blocks to be indexed
      * @return the size of an IndexRecord when it needs to index the specified number of blocks
      */
     public static int getRecordSizeForBlockCount(int blockCount) {
         return 20 + 4 * blockCount;
-    }  
+    }
 
     @Override
     public short getSid() {
@@ -154,13 +156,15 @@ public final class IndexRecord extends S
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public IndexRecord clone() {
-      IndexRecord rec = new IndexRecord();
-      rec.field_2_first_row = field_2_first_row;
-      rec.field_3_last_row_add1 = field_3_last_row_add1;
-      rec.field_4_zero = field_4_zero;
-      rec.field_5_dbcells = new IntList();
-      rec.field_5_dbcells.addAll(field_5_dbcells);
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public IndexRecord copy() {
+      return new IndexRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java Sun Dec 22 21:44:45 2019
@@ -21,11 +21,7 @@ import org.apache.poi.util.LittleEndianO
 import org.apache.poi.util.RecordFormatException;
 
 /**
- * Title: Interface End Record (0x00E2)<P>
- * Description: Shows where the Interface Records end (MMS)
- *  (has no fields)<P>
- * REFERENCE:  PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
+ * Shows where the Interface Records ends (MMS)
  */
 public final class InterfaceEndRecord extends StandardRecord {
 
@@ -61,4 +57,9 @@ public final class InterfaceEndRecord ex
     public short getSid() {
         return sid;
     }
+
+    @Override
+    public InterfaceEndRecord copy() {
+        return instance;
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java Sun Dec 22 21:44:45 2019
@@ -21,19 +21,22 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title: Interface Header Record (0x00E1)<P>
- * Description: Defines the beginning of Interface records (MMS)<P>
- * REFERENCE:  PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
+ * Defines the beginning of Interface records (MMS)
  */
 public final class InterfaceHdrRecord extends StandardRecord {
-    public final static short sid = 0x00E1;
-    private final int _codepage;
+    public static final short sid = 0x00E1;
 
     /**
      * suggested (and probably correct) default
      */
-    public final static int CODEPAGE = 0x04B0;
+    public static final int CODEPAGE = 0x04B0;
+
+    private final int _codepage;
+
+    public InterfaceHdrRecord(InterfaceHdrRecord other) {
+        super(other);
+        _codepage = other._codepage;
+    }
 
     public InterfaceHdrRecord(int codePage) {
         _codepage = codePage;
@@ -63,4 +66,9 @@ public final class InterfaceHdrRecord ex
     public short getSid() {
         return sid;
     }
+
+    @Override
+    public InterfaceHdrRecord copy() {
+        return new InterfaceHdrRecord(this);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java Sun Dec 22 21:44:45 2019
@@ -21,28 +21,30 @@ import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Iteration Record (0x0011)<p>
- * Description:  Tells whether to iterate over formula calculations or not
- *               (if a formula is dependent upon another formula's result)
- *               (odd feature for something that can only have 32 elements in
- *                a formula!)<p>
- * REFERENCE:  PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Tells whether to iterate over formula calculations or not.
+ * If a formula is dependent upon another formula's result.
+ * (odd feature for something that can only have 32 elements in a formula!)
  */
-public final class IterationRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x0011;
+public final class IterationRecord extends StandardRecord {
+    public static final short sid = 0x0011;
 
     private static final BitField iterationOn = BitFieldFactory.getInstance(0x0001);
 
     private int _flags;
 
+    public IterationRecord(IterationRecord other) {
+        super(other);
+        _flags = other._flags;
+    }
+
     public IterationRecord(boolean iterateOn) {
         _flags = iterationOn.setBoolean(0, iterateOn);
     }
 
-    public IterationRecord(RecordInputStream in)
-    {
+    public IterationRecord(RecordInputStream in) {
         _flags = in.readShort();
     }
 
@@ -85,7 +87,15 @@ public final class IterationRecord exten
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public IterationRecord clone() {
-        return new IterationRecord(getIteration());
+        return copy();
+    }
+
+    @Override
+    public IterationRecord copy() {
+        return new IterationRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java Sun Dec 22 21:44:45 2019
@@ -21,36 +21,43 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 
 /**
  * Label Record (0x0204) - read only support for strings stored directly in the cell...
- * Don't use this (except to read), use LabelSST instead <P>
- * REFERENCE:  PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
- * 
+ * Don't use this (except to read), use LabelSST instead
+ *
  * @see org.apache.poi.hssf.record.LabelSSTRecord
  */
-public final class LabelRecord extends Record implements CellValueRecordInterface, Cloneable {
-    private final static POILogger logger = POILogFactory.getLogger(LabelRecord.class);
+public final class LabelRecord extends Record implements CellValueRecordInterface {
+    private static final POILogger logger = POILogFactory.getLogger(LabelRecord.class);
 
-    public final static short sid = 0x0204;
+    public static final short sid = 0x0204;
 
-    private int               field_1_row;
-    private short             field_2_column;
-    private short             field_3_xf_index;
-    private short             field_4_string_len;
-    private byte              field_5_unicode_flag;
-    private String            field_6_value;
+    private int    field_1_row;
+    private short  field_2_column;
+    private short  field_3_xf_index;
+    private short  field_4_string_len;
+    private byte   field_5_unicode_flag;
+    private String field_6_value;
 
     /** Creates new LabelRecord */
-    public LabelRecord()
-    {
+    public LabelRecord() {}
+
+    public LabelRecord(LabelRecord other) {
+        super(other);
+        field_1_row = other.field_1_row;
+        field_2_column = other.field_2_column;
+        field_3_xf_index = other.field_3_xf_index;
+        field_4_string_len = other.field_4_string_len;
+        field_5_unicode_flag = other.field_5_unicode_flag;
+        field_6_value = other.field_6_value;
     }
 
     /**
      * @param in the RecordInputstream to read the record from
      */
-    public LabelRecord(RecordInputStream in)
-    {
+    public LabelRecord(RecordInputStream in) {
         field_1_row          = in.readUShort();
         field_2_column       = in.readShort();
         field_3_xf_index     = in.readShort();
@@ -182,14 +189,15 @@ public final class LabelRecord extends R
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public LabelRecord clone() {
-      LabelRecord rec = new LabelRecord();
-      rec.field_1_row = field_1_row;
-      rec.field_2_column = field_2_column;
-      rec.field_3_xf_index = field_3_xf_index;
-      rec.field_4_string_len = field_4_string_len;
-      rec.field_5_unicode_flag = field_5_unicode_flag;
-      rec.field_6_value = field_6_value;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public LabelRecord copy() {
+        return new LabelRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java Sun Dec 22 21:44:45 2019
@@ -19,18 +19,20 @@ package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Label SST Record<P>
- * Description:  Refers to a string in the shared string table and is a column value.<P>
- * REFERENCE:  PG 325 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Refers to a string in the shared string table and is a column value.
  */
-public final class LabelSSTRecord extends CellRecord implements Cloneable {
-    public final static short sid = 0xfd;
+public final class LabelSSTRecord extends CellRecord {
+    public static final short sid = 0xfd;
     private int field_4_sst_index;
 
-    public LabelSSTRecord() {
-    	// fields uninitialised
+    public LabelSSTRecord() {}
+
+    public LabelSSTRecord(LabelSSTRecord other) {
+        super(other);
+        field_4_sst_index = other.field_4_sst_index;
     }
 
     public LabelSSTRecord(RecordInputStream in) {
@@ -58,7 +60,7 @@ public final class LabelSSTRecord extend
     public int getSSTIndex() {
         return field_4_sst_index;
     }
-    
+
     @Override
     protected String getRecordName() {
     	return "LABELSST";
@@ -85,10 +87,15 @@ public final class LabelSSTRecord extend
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public LabelSSTRecord clone() {
-      LabelSSTRecord rec = new LabelSSTRecord();
-      copyBaseFields(rec);
-      rec.field_4_sst_index = field_4_sst_index;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public LabelSSTRecord copy() {
+        return new LabelSSTRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java Sun Dec 22 21:44:45 2019
@@ -16,11 +16,13 @@
 ==================================================================== */
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.common.Duplicatable;
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 import org.apache.poi.util.StringUtil;
 
 /**
@@ -89,6 +91,24 @@ public class LbsDataSubRecord extends Su
      */
     private boolean[] _bsels;
 
+    LbsDataSubRecord() {}
+
+    public LbsDataSubRecord(LbsDataSubRecord other) {
+        super(other);
+        _cbFContinued = other._cbFContinued;
+        _unknownPreFormulaInt = other._unknownPreFormulaInt;
+        _linkPtg = (other._linkPtg == null) ? null : other._linkPtg.copy();
+        _unknownPostFormulaByte = other._unknownPostFormulaByte;
+        _cLines = other._cLines;
+        _iSel = other._iSel;
+        _flags = other._flags;
+        _idEdit = other._idEdit;
+        _dropData = (other._dropData == null) ? null : other._dropData.copy();
+        _rgLines = (other._rgLines == null) ? null : other._rgLines.clone();
+        _bsels = (other._bsels == null) ? null : other._bsels.clone();
+    }
+
+
     /**
      * @param in the stream to read data from
      * @param cbFContinued the seconf short in the record header
@@ -154,10 +174,6 @@ public class LbsDataSubRecord extends Su
 
     }
 
-    LbsDataSubRecord(){
-
-    }
-
     /**
      *
      * @return a new instance of LbsDataSubRecord to construct auto-filters
@@ -259,9 +275,16 @@ public class LbsDataSubRecord extends Su
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public LbsDataSubRecord clone() {
-        // TODO: is immutable ???
-        return this;
+        return copy();
+    }
+
+    @Override
+    public LbsDataSubRecord copy() {
+        return new LbsDataSubRecord(this);
     }
 
     @Override
@@ -303,7 +326,7 @@ public class LbsDataSubRecord extends Su
     /**
      * This structure specifies properties of the dropdown list control
      */
-    public static class LbsDropData {
+    public static class LbsDropData implements Duplicatable {
         /**
          * Combo dropdown control
          */
@@ -318,7 +341,7 @@ public class LbsDataSubRecord extends Su
         public static final int STYLE_COMBO_SIMPLE_DROPDOWN = 2;
 
         /**
-         *  An unsigned integer that specifies the style of this dropdown. 
+         *  An unsigned integer that specifies the style of this dropdown.
          */
         private int _wStyle;
 
@@ -343,12 +366,20 @@ public class LbsDataSubRecord extends Su
          */
         private Byte _unused;
 
-        public LbsDropData(){
+        public LbsDropData() {
             _str = "";
             _unused = 0;
         }
 
-        public LbsDropData(LittleEndianInput in){
+        public LbsDropData(LbsDropData other) {
+            _wStyle = other._wStyle;
+            _cLine = other._cLine;
+            _dxMin = other._dxMin;
+            _str = other._str;
+            _unused = other._unused;
+        }
+
+        public LbsDropData(LittleEndianInput in) {
             _wStyle = in.readUShort();
             _cLine = in.readUShort();
             _dxMin = in.readUShort();
@@ -367,7 +398,7 @@ public class LbsDataSubRecord extends Su
          * <li>1: Combo Edit dropdown control</li>
          * <li>2: Simple dropdown control (just the dropdown button)</li>
          * </ul>
-         * 
+         *
          * @param style the style - see possible values
          */
         public void setStyle(int style){
@@ -376,7 +407,7 @@ public class LbsDataSubRecord extends Su
 
         /**
          * Set the number of lines to be displayed in the dropdown.
-         * 
+         *
          * @param num the number of lines to be displayed in the dropdown
          */
         public void setNumLines(int num){
@@ -417,5 +448,10 @@ public class LbsDataSubRecord extends Su
 
             return sb.toString();
         }
+
+        @Override
+        public LbsDropData copy() {
+            return new LbsDropData(this);
+        }
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org