Modified: poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DVRecord.java Sun Dec 22 
21:44:45 2019
@@ -25,64 +25,77 @@ import org.apache.poi.ss.util.CellRangeA
 import org.apache.poi.ss.util.CellRangeAddressList;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 import org.apache.poi.util.StringUtil;
 
 /**
- * Title:        DATAVALIDATION Record (0x01BE)<p>
- * Description:  This record stores data validation settings and a list of 
cell ranges
- *               which contain these settings. The data validation settings of 
a sheet
- *               are stored in a sequential list of DV records. This list is 
followed by
- *               DVAL record(s)
+ * This record stores data validation settings and a list of cell ranges which 
contain these settings.
+ * The data validation settings of a sheet are stored in a sequential list of 
DV records.
+ * This list is followed by DVAL record(s)
  */
-public final class DVRecord extends StandardRecord implements Cloneable {
-       public final static short sid = 0x01BE;
-       
+public final class DVRecord extends StandardRecord {
+       public static final short sid = 0x01BE;
+
        /** the unicode string used for error/prompt title/text when not 
present */
        private static final UnicodeString NULL_TEXT_STRING = new 
UnicodeString("\0");
 
+       /**
+        * Option flags field
+        *
+        * @see HSSFDataValidation utility class
+        */
+       private static final BitField opt_data_type                    = new 
BitField(0x0000000F);
+       private static final BitField opt_error_style                  = new 
BitField(0x00000070);
+       private static final BitField opt_string_list_formula          = new 
BitField(0x00000080);
+       private static final BitField opt_empty_cell_allowed           = new 
BitField(0x00000100);
+       private static final BitField opt_suppress_dropdown_arrow      = new 
BitField(0x00000200);
+       private static final BitField opt_show_prompt_on_cell_selected = new 
BitField(0x00040000);
+       private static final BitField opt_show_error_on_invalid_value  = new 
BitField(0x00080000);
+       private static final BitField opt_condition_operator           = new 
BitField(0x00700000);
+
        /** Option flags */
        private int _option_flags;
        /** Title of the prompt box, cannot be longer than 32 chars */
-       private UnicodeString _promptTitle;
+       private final UnicodeString _promptTitle;
        /** Title of the error box, cannot be longer than 32 chars */
-       private UnicodeString _errorTitle;
+       private final UnicodeString _errorTitle;
        /** Text of the prompt box, cannot be longer than 255 chars */
-       private UnicodeString _promptText;
+       private final UnicodeString _promptText;
        /** Text of the error box, cannot be longer than 255 chars */
-       private UnicodeString _errorText;
+       private final UnicodeString _errorText;
        /** Not used - Excel seems to always write 0x3FE0 */
        private short _not_used_1 = 0x3FE0;
        /** Formula data for first condition (RPN token array without size 
field) */
-       private Formula _formula1;
+       private final Formula _formula1;
        /** Not used - Excel seems to always write 0x0000 */
        @SuppressWarnings("RedundantFieldInitialization")
        private short _not_used_2 = 0x0000;
        /** Formula data for second condition (RPN token array without size 
field) */
-       private Formula _formula2;
+       private final Formula _formula2;
        /** Cell range address list with all affected ranges */
-       private CellRangeAddressList _regions;
+       private final CellRangeAddressList _regions;
 
-       /**
-        * Option flags field
-        * 
-        * @see HSSFDataValidation utility class
-        */
-       private static final BitField opt_data_type                    = new 
BitField(0x0000000F);
-       private static final BitField opt_error_style                  = new 
BitField(0x00000070);
-       private static final BitField opt_string_list_formula          = new 
BitField(0x00000080);
-       private static final BitField opt_empty_cell_allowed           = new 
BitField(0x00000100);
-       private static final BitField opt_suppress_dropdown_arrow      = new 
BitField(0x00000200);
-       private static final BitField opt_show_prompt_on_cell_selected = new 
BitField(0x00040000);
-       private static final BitField opt_show_error_on_invalid_value  = new 
BitField(0x00080000);
-       private static final BitField opt_condition_operator           = new 
BitField(0x00700000);
+       public DVRecord(DVRecord other) {
+               super(other);
+               _option_flags = other._option_flags;
+               _promptTitle = other._promptTitle.copy();
+               _errorTitle = other._errorTitle.copy();
+               _promptText = other._promptText.copy();
+               _errorText = other._errorText.copy();
+               _not_used_1 = other._not_used_1;
+               _formula1 = (other._formula1 == null) ? null : 
other._formula1.copy();
+               _not_used_2 = other._not_used_2;
+               _formula2 = (other._formula2 == null) ? null : 
other._formula2.copy();
+               _regions = (other._regions == null) ? null : 
other._regions.copy();
+       }
 
        public DVRecord(int validationType, int operator, int errorStyle, 
boolean emptyCellAllowed,
                        boolean suppressDropDownArrow, boolean isExplicitList,
-                       boolean showPromptBox, String promptTitle, String 
promptText, 
+                       boolean showPromptBox, String promptTitle, String 
promptText,
                        boolean showErrorBox, String errorTitle, String 
errorText,
                        Ptg[] formula1, Ptg[] formula2,
                        CellRangeAddressList regions) {
-               
+
                // check length-limits
                if(promptTitle != null && promptTitle.length() > 32) {
                        throw new IllegalStateException("Prompt-title cannot be 
longer than 32 characters, but had: " + promptTitle);
@@ -118,7 +131,6 @@ public final class DVRecord extends Stan
        }
 
        public DVRecord(RecordInputStream in) {
-
                _option_flags = in.readInt();
 
                _promptTitle = readUnicodeString(in);
@@ -144,7 +156,6 @@ public final class DVRecord extends Stan
                _regions = new CellRangeAddressList(in);
        }
 
-       // --> start option flags
        /**
         * @return the condition data type
         * @see 
org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType
@@ -276,7 +287,7 @@ public final class DVRecord extends Stan
 
        private static void appendFormula(StringBuilder sb, String label, 
Formula f) {
                sb.append(label);
-               
+
                if (f == null) {
                        sb.append("<empty>\n");
                        return;
@@ -291,7 +302,7 @@ public final class DVRecord extends Stan
        public void serialize(LittleEndianOutput out) {
 
                out.writeInt(_option_flags);
-               
+
                serializeUnicodeString(_promptTitle, out);
                serializeUnicodeString(_errorTitle, out);
                serializeUnicodeString(_promptText, out);
@@ -299,19 +310,19 @@ public final class DVRecord extends Stan
                out.writeShort(_formula1.getEncodedTokenSize());
                out.writeShort(_not_used_1);
                _formula1.serializeTokens(out);
-               
+
                out.writeShort(_formula2.getEncodedTokenSize());
                out.writeShort(_not_used_2);
                _formula2.serializeTokens(out);
-               
+
                _regions.serialize(out);
        }
 
        /**
         * When entered via the UI, Excel translates empty string into "\0"
         * While it is possible to encode the title/text as empty string (Excel 
doesn't exactly crash),
-        * the resulting tool-tip text / message box looks wrong.  It is best 
to do the same as the 
-        * Excel UI and encode 'not present' as "\0". 
+        * the resulting tool-tip text / message box looks wrong.  It is best 
to do the same as the
+        * Excel UI and encode 'not present' as "\0".
         */
        private static UnicodeString resolveTitleText(String str) {
                if (str == null || str.length() < 1) {
@@ -354,13 +365,18 @@ public final class DVRecord extends Stan
        public short getSid() {
                return sid;
        }
-       
-       /**
-        * Clones the object. Uses serialisation, as the
-        *  contents are somewhat complex
-        */
+
        @Override
+       @SuppressWarnings("squid:S2975")
+       @Deprecated
+       @Removal(version = "5.0.0")
        public DVRecord clone() {
-               return (DVRecord)cloneViaReserialise();
+               return copy();
+       }
+
+       /** Clones the object. */
+       @Override
+       public DVRecord copy() {
+               return new DVRecord(this);
        }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/DateWindow1904Record.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DateWindow1904Record.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DateWindow1904Record.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DateWindow1904Record.java Sun 
Dec 22 21:44:45 2019
@@ -15,33 +15,31 @@
    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:        Date Window 1904 Flag record <P>
- * Description:  Flag specifying whether 1904 date windowing is used.
- *               (tick toc tick toc...BOOM!) <P>
- * REFERENCE:  PG 280 Microsoft Excel 97 Developer's Kit (ISBN: 
1-57231-498-2)<P>
- * @author Andrew C. Oliver (acoliver at apache dot org)
+ * Flag specifying whether 1904 date windowing is used.
+ *
  * @version 2.0-pre
  */
 
-public final class DateWindow1904Record
-    extends StandardRecord
-{
-    public final static short sid = 0x22;
-    private short             field_1_window;
+public final class DateWindow1904Record extends StandardRecord {
+    public static final short sid = 0x22;
 
-    public DateWindow1904Record()
-    {
+    private short field_1_window;
+
+    public DateWindow1904Record() {}
+
+    public DateWindow1904Record(DateWindow1904Record other) {
+        super(other);
+        field_1_window = other.field_1_window;
     }
 
-    public DateWindow1904Record(RecordInputStream in)
-    {
+    public DateWindow1904Record(RecordInputStream in) {
         field_1_window = in.readShort();
     }
 
@@ -88,4 +86,9 @@ public final class DateWindow1904Record
     {
         return sid;
     }
+
+    @Override
+    public DateWindow1904Record copy() {
+        return new DateWindow1904Record(this);
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/DefaultColWidthRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DefaultColWidthRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DefaultColWidthRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DefaultColWidthRecord.java 
Sun Dec 22 21:44:45 2019
@@ -18,30 +18,32 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Default Column Width Record (0x0055) <P>
- * Description:  Specifies the default width for columns that have no specific
- *               width set.<P>
- * REFERENCE:  PG 302 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)
+ * Specifies the default width for columns that have no specific width set.
+ *
  * @version 2.0-pre
  */
-public final class DefaultColWidthRecord extends StandardRecord implements 
Cloneable {
-    public final static short sid = 0x0055;
-    private int             field_1_col_width;
+public final class DefaultColWidthRecord extends StandardRecord {
+    public static final short sid = 0x0055;
 
     /**
      *  The default column width is 8 characters
      */
-    public final static int DEFAULT_COLUMN_WIDTH = 0x0008;
+    public static final int DEFAULT_COLUMN_WIDTH = 0x0008;
 
-    public DefaultColWidthRecord()
-    {
+    private int field_1_col_width;
+
+    public DefaultColWidthRecord() {
         field_1_col_width = DEFAULT_COLUMN_WIDTH;
     }
 
+    public DefaultColWidthRecord(DefaultColWidthRecord other) {
+        super(other);
+        field_1_col_width = other.field_1_col_width;
+    }
+
     public DefaultColWidthRecord(RecordInputStream in)
     {
         field_1_col_width = in.readUShort();
@@ -92,9 +94,15 @@ public final class DefaultColWidthRecord
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public DefaultColWidthRecord clone() {
-      DefaultColWidthRecord rec = new DefaultColWidthRecord();
-      rec.field_1_col_width = field_1_col_width;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public DefaultColWidthRecord copy() {
+      return new DefaultColWidthRecord(this);
     }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/DefaultRowHeightRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DefaultRowHeightRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DefaultRowHeightRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DefaultRowHeightRecord.java 
Sun Dec 22 21:44:45 2019
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -20,35 +19,35 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Default Row Height Record
- * Description:  Row height for rows with undefined or not explicitly defined
- *               heights.
- * REFERENCE:  PG 301 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 height for rows with undefined or not explicitly defined heights.
+ *
  * @version 2.0-pre
  */
 
-public final class DefaultRowHeightRecord extends StandardRecord implements 
Cloneable {
-    public final static short sid = 0x225;
-    private short             field_1_option_flags;
-    private short             field_2_row_height;
+public final class DefaultRowHeightRecord extends StandardRecord {
+    public static final short sid = 0x225;
 
-    /**
-     * The default row height for empty rows is 255 twips (255 / 20 == 12.75 
points)
-     */
+    /** The default row height for empty rows is 255 twips (255 / 20 == 12.75 
points) */
     public static final short DEFAULT_ROW_HEIGHT = 0xFF;
 
-    public DefaultRowHeightRecord()
-    {
+    private short field_1_option_flags;
+    private short field_2_row_height;
+
+    public DefaultRowHeightRecord() {
         field_1_option_flags = 0x0000;
         field_2_row_height = DEFAULT_ROW_HEIGHT;
     }
 
-    public DefaultRowHeightRecord(RecordInputStream in)
-    {
+    public DefaultRowHeightRecord(DefaultRowHeightRecord other) {
+        super(other);
+        field_1_option_flags = other.field_1_option_flags;
+        field_2_row_height = other.field_2_row_height;
+    }
+
+    public DefaultRowHeightRecord(RecordInputStream in) {
         field_1_option_flags = in.readShort();
         field_2_row_height   = in.readShort();
     }
@@ -121,10 +120,15 @@ public final class DefaultRowHeightRecor
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public DefaultRowHeightRecord clone() {
-      DefaultRowHeightRecord rec = new DefaultRowHeightRecord();
-      rec.field_1_option_flags = field_1_option_flags;
-      rec.field_2_row_height = field_2_row_height;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public DefaultRowHeightRecord copy() {
+      return new DefaultRowHeightRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/DeltaRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DeltaRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DeltaRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DeltaRecord.java Sun Dec 22 
21:44:45 2019
@@ -18,15 +18,12 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
-/**
- * Title:        Delta Record (0x0010)<p>
- * Description:  controls the accuracy of the calculations<p>
- * REFERENCE:  PG 303 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
- */
-public final class DeltaRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x0010;
-    public final static double DEFAULT_VALUE = 0.0010;   // should be .001
+/** Controls the accuracy of the calculations */
+public final class DeltaRecord extends StandardRecord {
+    public static final short sid = 0x0010;
+    public static final double DEFAULT_VALUE = 0.0010;
 
     // a double is an IEEE 8-byte float...damn IEEE and their goofy standards 
an
     // ambiguous numeric identifiers
@@ -36,6 +33,11 @@ public final class DeltaRecord extends S
         field_1_max_change = maxChange;
     }
 
+    public DeltaRecord(DeltaRecord other) {
+        super(other);
+        field_1_max_change = other.field_1_max_change;
+    }
+
     public DeltaRecord(RecordInputStream in) {
         field_1_max_change = in.readDouble();
     }
@@ -70,7 +72,15 @@ public final class DeltaRecord extends S
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public DeltaRecord clone() {
+        return copy();
+    }
+
+    @Override
+    public DeltaRecord copy() {
         // immutable
         return this;
     }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/DimensionsRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DimensionsRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DimensionsRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DimensionsRecord.java Sun Dec 
22 21:44:45 2019
@@ -15,41 +15,44 @@
    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.POILogFactory;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Removal;
 
 /**
- * Title:        Dimensions Record<P>
- * Description:  provides the minumum and maximum bounds
- *               of a sheet.<P>
- * REFERENCE:  PG 303 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)
+ * Provides the minumum and maximum bounds of a sheet.
+ *
  * @version 2.0-pre
  */
 
-public final class DimensionsRecord extends StandardRecord implements 
Cloneable {
+public final class DimensionsRecord extends StandardRecord {
 
     private static final POILogger logger = 
POILogFactory.getLogger(DimensionsRecord.class);
 
-    public final static short sid = 0x200;
+    public static final short sid = 0x200;
     private int               field_1_first_row;
     private int               field_2_last_row;   // plus 1
     private short             field_3_first_col;
     private short             field_4_last_col;
     private short             field_5_zero;       // must be 0 (reserved)
 
-    public DimensionsRecord()
-    {
+    public DimensionsRecord() {}
+
+    public DimensionsRecord(DimensionsRecord other) {
+        super(other);
+        field_1_first_row = other.field_1_first_row;
+        field_2_last_row  = other.field_2_last_row;
+        field_3_first_col = other.field_3_first_col;
+        field_4_last_col  = other.field_4_last_col;
+        field_5_zero      = other.field_5_zero;
     }
 
-    public DimensionsRecord(RecordInputStream in)
-    {
+    public DimensionsRecord(RecordInputStream in) {
         field_1_first_row = in.readInt();
         field_2_last_row  = in.readInt();
         field_3_first_col = in.readShort();
@@ -179,13 +182,15 @@ public final class DimensionsRecord exte
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public DimensionsRecord clone() {
-      DimensionsRecord rec = new DimensionsRecord();
-      rec.field_1_first_row = field_1_first_row;
-      rec.field_2_last_row = field_2_last_row;
-      rec.field_3_first_col = field_3_first_col;
-      rec.field_4_last_col = field_4_last_col;
-      rec.field_5_zero = field_5_zero;
-      return rec;
+        return copy();
+    }
+
+    @Override
+    public DimensionsRecord copy() {
+      return new DimensionsRecord(this);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DrawingGroupRecord.java Sun 
Dec 22 21:44:45 2019
@@ -17,13 +17,13 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.ddf.NullEscherSerializationListener;
 import org.apache.poi.util.LittleEndian;
 
-import java.util.Iterator;
-import java.util.List;
-
 
 public final class DrawingGroupRecord extends AbstractEscherHolderRecord {
     public static final short sid = 0xEB;
@@ -31,12 +31,13 @@ public final class DrawingGroupRecord ex
     static final int MAX_RECORD_SIZE = 8228;
     private static final int MAX_DATA_SIZE = MAX_RECORD_SIZE - 4;
 
-    public DrawingGroupRecord()
-    {
+    public DrawingGroupRecord() {}
+
+    public DrawingGroupRecord(DrawingGroupRecord other) {
+        super(other);
     }
 
-    public DrawingGroupRecord( RecordInputStream in )
-    {
+    public DrawingGroupRecord( RecordInputStream in ) {
         super( in );
     }
 
@@ -136,4 +137,9 @@ public final class DrawingGroupRecord ex
         LittleEndian.putShort(data, 0 + offset, ContinueRecord.sid);
         LittleEndian.putShort(data, 2 + offset, (short) sizeExcludingHeader);
     }
+
+    @Override
+    public DrawingGroupRecord copy() {
+        return new DrawingGroupRecord(this);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecord.java Sun Dec 22 
21:44:45 2019
@@ -18,10 +18,9 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
-/**
- * DrawingRecord (0x00EC)
- */
-public final class DrawingRecord extends StandardRecord implements Cloneable {
+import org.apache.poi.util.Removal;
+
+public final class DrawingRecord extends StandardRecord {
     public static final short sid = 0x00EC;
 
     private static final byte[] EMPTY_BYTE_ARRAY = {};
@@ -33,6 +32,13 @@ public final class DrawingRecord extends
         recordData = EMPTY_BYTE_ARRAY;
     }
 
+    public DrawingRecord(DrawingRecord other) {
+        super(other);
+        recordData = (other.recordData == null) ? null : 
other.recordData.clone();
+        // TODO - this code probably never copies a contd array ...
+        contd = (other.contd == null) ? null : other.contd.clone();
+    }
+
     public DrawingRecord(RecordInputStream in) {
         recordData = in.readRemainder();
     }
@@ -69,20 +75,21 @@ public final class DrawingRecord extends
         recordData = thedata;
     }
 
+    @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
+    public DrawingRecord clone() {
+        return copy();
+    }
+
     /**
      * Cloning of drawing records must be executed through HSSFPatriarch, 
because all id's must be changed
      * @return cloned drawing records
      */
     @Override
-    public DrawingRecord clone() {
-        DrawingRecord rec = new DrawingRecord();
-        rec.recordData = recordData.clone();
-        if (contd != null) {
-            // TODO - this code probably never executes
-            rec.contd = contd.clone();
-        }
-
-        return rec;
+    public DrawingRecord copy() {
+        return new DrawingRecord(this);
     }
 
     @Override

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecordForBiffViewer.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecordForBiffViewer.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecordForBiffViewer.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/DrawingRecordForBiffViewer.java 
Sun Dec 22 21:44:45 2019
@@ -26,8 +26,10 @@ import java.io.ByteArrayInputStream;
 public final class DrawingRecordForBiffViewer extends 
AbstractEscherHolderRecord {
     public static final short sid = 0xEC;
 
-    public DrawingRecordForBiffViewer()
-    {
+    public DrawingRecordForBiffViewer() {}
+
+    public DrawingRecordForBiffViewer(DrawingRecordForBiffViewer other) {
+        super(other);
     }
 
     public DrawingRecordForBiffViewer( RecordInputStream in)
@@ -59,4 +61,9 @@ public final class DrawingRecordForBiffV
     {
         return sid;
     }
+
+    @Override
+    public DrawingRecordForBiffViewer copy() {
+        return new DrawingRecordForBiffViewer(this);
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/DrawingSelectionRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/DrawingSelectionRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/DrawingSelectionRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/DrawingSelectionRecord.java 
Sun Dec 22 21:44:45 2019
@@ -20,13 +20,14 @@ package org.apache.poi.hssf.record;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
  * MsoDrawingSelection (0x00ED)<p>
  * Reference:
  * [MS-OGRAPH].pdf sec 2.4.69
  */
-public final class DrawingSelectionRecord extends StandardRecord implements 
Cloneable {
+public final class DrawingSelectionRecord extends StandardRecord {
        public static final short sid = 0x00ED;
 
        /**
@@ -44,6 +45,12 @@ public final class DrawingSelectionRecor
                private final int _type;
                private final int _length;
 
+               public OfficeArtRecordHeader(OfficeArtRecordHeader other) {
+                       _verAndInstance = other._verAndInstance;
+                       _type = other._type;
+                       _length = other._length;
+               }
+
                public OfficeArtRecordHeader(LittleEndianInput in) {
                        _verAndInstance = in.readUShort();
                        _type = in.readUShort();
@@ -57,11 +64,10 @@ public final class DrawingSelectionRecor
                }
 
                public String debugFormatAsString() {
-                       StringBuilder sb = new StringBuilder(32);
-                       
sb.append("ver+inst=").append(HexDump.shortToHex(_verAndInstance));
-                       sb.append(" type=").append(HexDump.shortToHex(_type));
-                       sb.append(" len=").append(HexDump.intToHex(_length));
-                       return sb.toString();
+                       return
+                               "ver+inst=" + 
HexDump.shortToHex(_verAndInstance) +
+                               " type=" + HexDump.shortToHex(_type) +
+                               " len=" + HexDump.intToHex(_length);
                }
        }
 
@@ -93,7 +99,7 @@ public final class DrawingSelectionRecor
        }
 
        protected int getDataSize() {
-               return OfficeArtRecordHeader.ENCODED_SIZE 
+               return OfficeArtRecordHeader.ENCODED_SIZE
                        + 12 // 3 int fields
                        + _shapeIds.length * 4;
        }
@@ -109,7 +115,15 @@ public final class DrawingSelectionRecor
        }
 
        @Override
+       @SuppressWarnings("squid:S2975")
+       @Deprecated
+       @Removal(version = "5.0.0")
        public DrawingSelectionRecord clone() {
+               return copy();
+       }
+
+       @Override
+       public DrawingSelectionRecord copy() {
                // currently immutable
                return this;
        }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/EOFRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/EOFRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/EOFRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/EOFRecord.java Sun Dec 22 
21:44:45 2019
@@ -18,33 +18,25 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
- * End Of File record.
- * <P>
- * Description:  Marks the end of records belonging to a particular object in 
the
- *               HSSF File<P>
- * REFERENCE:  PG 307 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)
+ * Marks the end of records belonging to a particular object in the HSSF File
+ *
  * @version 2.0-pre
  */
-public final class EOFRecord extends StandardRecord implements Cloneable {
-    public final static short sid = 0x0A;
+public final class EOFRecord extends StandardRecord {
+    public static final short sid = 0x0A;
        public static final int ENCODED_SIZE = 4;
 
        public static final EOFRecord instance = new EOFRecord();
-       
-    private EOFRecord() {
-       // no data fields
-    }
+
+    private EOFRecord() {}
 
     /**
      * @param in unused (since this record has no data)
      */
-    public EOFRecord(RecordInputStream in)
-    {
-    }
+    public EOFRecord(RecordInputStream in) {}
 
     public String toString()
     {
@@ -68,7 +60,15 @@ public final class EOFRecord extends Sta
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public EOFRecord clone() {
+        return copy();
+    }
+
+    @Override
+    public EOFRecord copy() {
       return instance;
     }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/EmbeddedObjectRefSubRecord.java 
Sun Dec 22 21:44:45 2019
@@ -33,6 +33,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;
 
 /**
@@ -40,7 +41,7 @@ import org.apache.poi.util.StringUtil;
  * A sub-record within the OBJ record which stores a reference to an object
  * stored in a separate entry within the OLE2 compound file.
  */
-public final class EmbeddedObjectRefSubRecord extends SubRecord implements 
Cloneable {
+public final class EmbeddedObjectRefSubRecord extends SubRecord {
        private static POILogger logger = 
POILogFactory.getLogger(EmbeddedObjectRefSubRecord.class);
        //arbitrarily selected; may need to increase
        private static final int MAX_RECORD_LENGTH = 100_000;
@@ -73,8 +74,16 @@ public final class EmbeddedObjectRefSubR
                field_4_ole_classname = null;
        }
 
-       public short getSid() {
-               return sid;
+       public EmbeddedObjectRefSubRecord(EmbeddedObjectRefSubRecord other) {
+               super(other);
+               field_1_unknown_int = other.field_1_unknown_int;
+               field_2_refPtg = (other.field_2_refPtg == null) ? null : 
other.field_2_refPtg.copy();
+               field_2_unknownFormulaData = (other.field_2_unknownFormulaData 
== null) ? null : other.field_2_unknownFormulaData.clone();
+               field_3_unicode_flag = other.field_3_unicode_flag;
+               field_4_ole_classname = other.field_4_ole_classname;
+               field_4_unknownByte = other.field_4_unknownByte;
+               field_5_stream_id = other.field_5_stream_id;
+               field_6_unknown = (other.field_6_unknown == null) ? null : 
other.field_6_unknown.clone();
        }
 
        public EmbeddedObjectRefSubRecord(LittleEndianInput in, int size) {
@@ -158,6 +167,10 @@ public final class EmbeddedObjectRefSubR
                field_6_unknown = readRawData(in, remaining);
        }
 
+       public short getSid() {
+               return sid;
+       }
+
        private static Ptg readRefPtg(byte[] formulaRawBytes) {
                LittleEndianInput in = new LittleEndianInputStream(new 
ByteArrayInputStream(formulaRawBytes));
                byte ptgSid = in.readByte();
@@ -310,8 +323,16 @@ public final class EmbeddedObjectRefSubR
        }
 
        @Override
+       @SuppressWarnings("squid:S2975")
+       @Deprecated
+       @Removal(version = "5.0.0")
        public EmbeddedObjectRefSubRecord clone() {
-               return this; // TODO proper clone
+               return copy();
+       }
+
+       @Override
+       public EmbeddedObjectRefSubRecord copy() {
+               return new EmbeddedObjectRefSubRecord(this);
        }
 
        public String toString() {
@@ -339,15 +360,15 @@ public final class EmbeddedObjectRefSubR
                sb.append("[/ftPictFmla]");
                return sb.toString();
        }
-       
+
        public void setUnknownFormulaData(byte[] formularData) {
                field_2_unknownFormulaData = formularData;
        }
-       
+
        public void setOleClassname(String oleClassname) {
                field_4_ole_classname = oleClassname;
        }
-       
+
        public void setStorageId(int storageId) {
                field_5_stream_id = storageId;
        }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/EndSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/EndSubRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/EndSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/EndSubRecord.java Sun Dec 22 
21:44:45 2019
@@ -14,27 +14,25 @@
    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.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.util.Removal;
 
 /**
  * ftEnd (0x0000)<p>
- * 
+ *
  * The end data record is used to denote the end of the subrecords.
  */
-public final class EndSubRecord extends SubRecord implements Cloneable {
+public final class EndSubRecord extends SubRecord {
     // Note - zero sid is somewhat unusual (compared to plain Records)
-    public final static short sid = 0x0000;
+    public static final short sid = 0x0000;
     private static final int ENCODED_SIZE = 0;
 
-    public EndSubRecord()
-    {
-
-    }
+    public EndSubRecord() {}
 
     /**
      * @param in unused (since this record has no data)
@@ -76,8 +74,15 @@ public final class EndSubRecord extends
     }
 
     @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
     public EndSubRecord clone() {
+        return copy();
+    }
 
+    @Override
+    public EndSubRecord copy() {
         return new EndSubRecord();
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/EscherAggregate.java Sun Dec 
22 21:44:45 2019
@@ -85,7 +85,7 @@ import org.apache.poi.util.RecordFormatE
 
 public final class EscherAggregate extends AbstractEscherHolderRecord {
     public static final short sid = 9876; // not a real sid - dummy value
-    private static POILogger log = 
POILogFactory.getLogger(EscherAggregate.class);
+    private static final POILogger log = 
POILogFactory.getLogger(EscherAggregate.class);
     //arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 100_000_000;
 
@@ -317,6 +317,13 @@ public final class EscherAggregate exten
         }
     }
 
+    public EscherAggregate(EscherAggregate other) {
+        super(other);
+        // shallow copy, because the aggregates doesn't own the records
+        shapeToObj.putAll(other.shapeToObj);
+        tailRec.putAll(other.tailRec);
+    }
+
     /**
      * @return Returns the current sid.
      */
@@ -814,4 +821,9 @@ public final class EscherAggregate exten
     public void removeTailRecord(NoteRecord note) {
         tailRec.remove(note.getShapeId());
     }
+
+    @Override
+    public EscherAggregate copy() {
+        return new EscherAggregate(this);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ExtSSTRecord.java Sun Dec 22 
21:44:45 2019
@@ -17,28 +17,27 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.ArrayList;
+import java.util.stream.Stream;
+
 import org.apache.poi.hssf.record.cont.ContinuableRecord;
 import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
 import org.apache.poi.util.LittleEndianOutput;
 
-import java.util.ArrayList;
-
 /**
- * Title:        Extended Static String Table (0x00FF)<p>
- * Description: This record is used for a quick lookup into the SST record. 
This
- *              record breaks the SST table into a set of buckets. The offsets
- *              to these buckets within the SST record are kept as well as the
- *              position relative to the start of the SST record.<p>
- * REFERENCE:  PG 313 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
+ * Extended Static String Table (0x00FF)<p>
+ * This record is used for a quick lookup into the SST record. This record 
breaks the SST table
+ * into a set of buckets. The offsets to these buckets within the SST record 
are kept as well as
+ * the position relative to the start of the SST record.
  */
 public final class ExtSSTRecord extends ContinuableRecord {
-    public final static short sid = 0x00FF;
+    public static final short sid = 0x00FF;
     public static final int DEFAULT_BUCKET_SIZE = 8;
     //Can't seem to find this documented but from the biffviewer it is clear 
that
     //Excel only records the indexes for the first 128 buckets.
     public static final int MAX_BUCKETS = 128;
-    
-    
+
+
     public static final class InfoSubRecord {
        public static final int ENCODED_SIZE = 8;
         private int field_1_stream_pos;          // stream pointer to the SST 
record
@@ -48,7 +47,7 @@ public final class ExtSSTRecord extends
 
         /**
          * Creates new ExtSSTInfoSubRecord
-         * 
+         *
          * @param streamPos stream pointer to the SST record
          * @param bucketSstOffset ... don't really understand this yet
          */
@@ -57,6 +56,12 @@ public final class ExtSSTRecord extends
             field_2_bucket_sst_offset = bucketSstOffset;
         }
 
+        public InfoSubRecord(InfoSubRecord other) {
+            field_1_stream_pos        = other.field_1_stream_pos;
+            field_2_bucket_sst_offset = other.field_2_bucket_sst_offset;
+            field_3_zero              = other.field_3_zero;
+        }
+
         public InfoSubRecord(RecordInputStream in)
         {
             field_1_stream_pos        = in.readInt();
@@ -78,8 +83,8 @@ public final class ExtSSTRecord extends
             out.writeShort(field_3_zero);
         }
     }
-    
-    
+
+
     private short _stringsPerBucket;
     private InfoSubRecord[] _sstInfos;
 
@@ -89,6 +94,12 @@ public final class ExtSSTRecord extends
         _sstInfos = new InfoSubRecord[0];
     }
 
+    public ExtSSTRecord(ExtSSTRecord other) {
+        _stringsPerBucket = other._stringsPerBucket;
+        _sstInfos = (other._sstInfos == null) ? null
+            : 
Stream.of(other._sstInfos).map(InfoSubRecord::new).toArray(InfoSubRecord[]::new);
+    }
+
     public ExtSSTRecord(RecordInputStream in) {
         _stringsPerBucket = in.readShort();
 
@@ -161,9 +172,9 @@ public final class ExtSSTRecord extends
 
     /**
      * Given a number of strings (in the sst), returns the size of the extsst 
record
-     * 
+     *
      * @param numStrings the number of strings
-     * 
+     *
      * @return the size of the extsst record
      */
     public static int getRecordSizeForStrings(int numStrings) {
@@ -181,4 +192,9 @@ public final class ExtSSTRecord extends
             _sstInfos[i] = new InfoSubRecord(bucketAbsoluteOffsets[i], 
bucketRelativeOffsets[i]);
         }
     }
+
+    @Override
+    public ExtSSTRecord copy() {
+        return new ExtSSTRecord(this);
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ExtendedFormatRecord.java Sun 
Dec 22 21:44:45 2019
@@ -14,7 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 
 package org.apache.poi.hssf.record;
 
@@ -23,179 +23,164 @@ import org.apache.poi.util.BitFieldFacto
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title:        Extended Format Record
- * Description:  Probably one of the more complex records.  There are two 
breeds:
- *               Style and Cell.
- *<P>
- *               It should be noted that fields in the extended format record 
are
- *               somewhat arbitrary.  Almost all of the fields are bit-level, 
but
- *               we name them as best as possible by functional group.  In some
- *               places this is better than others.
- *<P>
+ * Probably one of the more complex records.<p>
+ * There are two breeds: Style and Cell.<p>
+ * It should be noted that fields in the extended format record are somewhat 
arbitrary.
+ * Almost all of the fields are bit-level, but we name them as best as 
possible by functional group.
+ * In some places this is better than others.
  *
- * REFERENCE:  PG 426 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
-
  * @since 2.0-pre
  */
 
-public final class ExtendedFormatRecord
-    extends StandardRecord
-{
-    public static final short     sid                 = 0xE0;
+public final class ExtendedFormatRecord extends StandardRecord {
+    public static final short sid                 = 0xE0;
 
     // null constant
-    public static final short     NULL                = (short)0xfff0;
+    public static final short NULL                = (short)0xfff0;
 
     // xf type
-    public static final short     XF_STYLE            = 1;
-    public static final short     XF_CELL             = 0;
+    public static final short XF_STYLE            = 1;
+    public static final short XF_CELL             = 0;
 
     // borders
-    public static final short     NONE                = 0x0;
-    public static final short     THIN                = 0x1;
-    public static final short     MEDIUM              = 0x2;
-    public static final short     DASHED              = 0x3;
-    public static final short     DOTTED              = 0x4;
-    public static final short     THICK               = 0x5;
-    public static final short     DOUBLE              = 0x6;
-    public static final short     HAIR                = 0x7;
-    public static final short     MEDIUM_DASHED       = 0x8;
-    public static final short     DASH_DOT            = 0x9;
-    public static final short     MEDIUM_DASH_DOT     = 0xA;
-    public static final short     DASH_DOT_DOT        = 0xB;
-    public static final short     MEDIUM_DASH_DOT_DOT = 0xC;
-    public static final short     SLANTED_DASH_DOT    = 0xD;
+    public static final short NONE                = 0x0;
+    public static final short THIN                = 0x1;
+    public static final short MEDIUM              = 0x2;
+    public static final short DASHED              = 0x3;
+    public static final short DOTTED              = 0x4;
+    public static final short THICK               = 0x5;
+    public static final short DOUBLE              = 0x6;
+    public static final short HAIR                = 0x7;
+    public static final short MEDIUM_DASHED       = 0x8;
+    public static final short DASH_DOT            = 0x9;
+    public static final short MEDIUM_DASH_DOT     = 0xA;
+    public static final short DASH_DOT_DOT        = 0xB;
+    public static final short MEDIUM_DASH_DOT_DOT = 0xC;
+    public static final short SLANTED_DASH_DOT    = 0xD;
 
     // alignment
-    public static final short     GENERAL             = 0x0;
-    public static final short     LEFT                = 0x1;
-    public static final short     CENTER              = 0x2;
-    public static final short     RIGHT               = 0x3;
-    public static final short     FILL                = 0x4;
-    public static final short     JUSTIFY             = 0x5;
-    public static final short     CENTER_SELECTION    = 0x6;
+    public static final short GENERAL             = 0x0;
+    public static final short LEFT                = 0x1;
+    public static final short CENTER              = 0x2;
+    public static final short RIGHT               = 0x3;
+    public static final short FILL                = 0x4;
+    public static final short JUSTIFY             = 0x5;
+    public static final short CENTER_SELECTION    = 0x6;
 
     // vertical alignment
-    public static final short     VERTICAL_TOP        = 0x0;
-    public static final short     VERTICAL_CENTER     = 0x1;
-    public static final short     VERTICAL_BOTTOM     = 0x2;
-    public static final short     VERTICAL_JUSTIFY    = 0x3;
+    public static final short VERTICAL_TOP        = 0x0;
+    public static final short VERTICAL_CENTER     = 0x1;
+    public static final short VERTICAL_BOTTOM     = 0x2;
+    public static final short VERTICAL_JUSTIFY    = 0x3;
 
     // fill
-    public static final short     NO_FILL             = 0  ;
-    public static final short     SOLID_FILL          = 1  ;
-    public static final short     FINE_DOTS           = 2  ;
-    public static final short     ALT_BARS            = 3  ;
-    public static final short     SPARSE_DOTS         = 4  ;
-    public static final short     THICK_HORZ_BANDS    = 5  ;
-    public static final short     THICK_VERT_BANDS    = 6  ;
-    public static final short     THICK_BACKWARD_DIAG = 7  ;
-    public static final short     THICK_FORWARD_DIAG  = 8  ;
-    public static final short     BIG_SPOTS           = 9  ;
-    public static final short     BRICKS              = 10 ;
-    public static final short     THIN_HORZ_BANDS     = 11 ;
-    public static final short     THIN_VERT_BANDS     = 12 ;
-    public static final short     THIN_BACKWARD_DIAG  = 13 ;
-    public static final short     THIN_FORWARD_DIAG   = 14 ;
-    public static final short     SQUARES             = 15 ;
-    public static final short     DIAMONDS            = 16 ;
-
-    // fields in BOTH style and Cell XF records
-    private short                 field_1_font_index;             // not 
bit-mapped
-    private short                 field_2_format_index;           // not 
bit-mapped
+    public static final short NO_FILL             = 0;
+    public static final short SOLID_FILL          = 1;
+    public static final short FINE_DOTS           = 2;
+    public static final short ALT_BARS            = 3;
+    public static final short SPARSE_DOTS         = 4;
+    public static final short THICK_HORZ_BANDS    = 5;
+    public static final short THICK_VERT_BANDS    = 6;
+    public static final short THICK_BACKWARD_DIAG = 7;
+    public static final short THICK_FORWARD_DIAG  = 8;
+    public static final short BIG_SPOTS           = 9;
+    public static final short BRICKS              = 10;
+    public static final short THIN_HORZ_BANDS     = 11;
+    public static final short THIN_VERT_BANDS     = 12;
+    public static final short THIN_BACKWARD_DIAG  = 13;
+    public static final short THIN_FORWARD_DIAG   = 14;
+    public static final short SQUARES             = 15;
+    public static final short DIAMONDS            = 16;
 
     // field_3_cell_options bit map
-    private static final BitField _locked       = 
BitFieldFactory.getInstance(0x0001);
-    private static final BitField _hidden       = 
BitFieldFactory.getInstance(0x0002);
-    private static final BitField _xf_type      = 
BitFieldFactory.getInstance(0x0004);
-    private static final BitField _123_prefix   = 
BitFieldFactory.getInstance(0x0008);
-    private static final BitField _parent_index = 
BitFieldFactory.getInstance(0xFFF0);
-    private short                 field_3_cell_options;
+    private static final BitField _locked       = bf(0x0001);
+    private static final BitField _hidden       = bf(0x0002);
+    private static final BitField _xf_type      = bf(0x0004);
+    private static final BitField _123_prefix   = bf(0x0008);
+    private static final BitField _parent_index = bf(0xFFF0);
 
     // field_4_alignment_options bit map
-    private static final BitField _alignment          = 
BitFieldFactory.getInstance(0x0007);
-    private static final BitField _wrap_text          = 
BitFieldFactory.getInstance(0x0008);
-    private static final BitField _vertical_alignment = 
BitFieldFactory.getInstance(0x0070);
-    private static final BitField _justify_last       = 
BitFieldFactory.getInstance(0x0080);
-    private static final BitField _rotation           = 
BitFieldFactory.getInstance(0xFF00);
-    private short                 field_4_alignment_options;
+    private static final BitField _alignment          = bf(0x0007);
+    private static final BitField _wrap_text          = bf(0x0008);
+    private static final BitField _vertical_alignment = bf(0x0070);
+    private static final BitField _justify_last       = bf(0x0080);
+    private static final BitField _rotation           = bf(0xFF00);
 
     // field_5_indention_options
-    private static final BitField _indent                         =
-        BitFieldFactory.getInstance(0x000F);
-    private static final BitField _shrink_to_fit                  =
-        BitFieldFactory.getInstance(0x0010);
-    private static final BitField _merge_cells                    =
-        BitFieldFactory.getInstance(0x0020);
-    private static final BitField _reading_order                  =
-        BitFieldFactory.getInstance(0x00C0);
+    private static final BitField _indent        = bf(0x000F);
+    private static final BitField _shrink_to_fit = bf(0x0010);
+    private static final BitField _merge_cells   = bf(0x0020);
+    private static final BitField _reading_order = bf(0x00C0);
 
     // apparently bits 8 and 9 are unused
-    private static final BitField _indent_not_parent_format       =
-        BitFieldFactory.getInstance(0x0400);
-    private static final BitField _indent_not_parent_font         =
-        BitFieldFactory.getInstance(0x0800);
-    private static final BitField _indent_not_parent_alignment    =
-        BitFieldFactory.getInstance(0x1000);
-    private static final BitField _indent_not_parent_border       =
-        BitFieldFactory.getInstance(0x2000);
-    private static final BitField _indent_not_parent_pattern      =
-        BitFieldFactory.getInstance(0x4000);
-    private static final BitField _indent_not_parent_cell_options =
-        BitFieldFactory.getInstance(0x8000);
-    private short                 field_5_indention_options;
+    private static final BitField _indent_not_parent_format       = bf(0x0400);
+    private static final BitField _indent_not_parent_font         = bf(0x0800);
+    private static final BitField _indent_not_parent_alignment    = bf(0x1000);
+    private static final BitField _indent_not_parent_border       = bf(0x2000);
+    private static final BitField _indent_not_parent_pattern      = bf(0x4000);
+    private static final BitField _indent_not_parent_cell_options = bf(0x8000);
 
     // field_6_border_options bit map
-    private static final BitField _border_left   = 
BitFieldFactory.getInstance(0x000F);
-    private static final BitField _border_right  = 
BitFieldFactory.getInstance(0x00F0);
-    private static final BitField _border_top    = 
BitFieldFactory.getInstance(0x0F00);
-    private static final BitField _border_bottom = 
BitFieldFactory.getInstance(0xF000);
-    private short                 field_6_border_options;
+    private static final BitField _border_left   = bf(0x000F);
+    private static final BitField _border_right  = bf(0x00F0);
+    private static final BitField _border_top    = bf(0x0F00);
+    private static final BitField _border_bottom = bf(0xF000);
 
     // all three of the following attributes are palette options
     // field_7_palette_options bit map
-    private static final BitField _left_border_palette_idx  =
-        BitFieldFactory.getInstance(0x007F);
-    private static final BitField _right_border_palette_idx =
-        BitFieldFactory.getInstance(0x3F80);
-    private static final BitField _diag                     =
-        BitFieldFactory.getInstance(0xC000);
-    private short                 field_7_palette_options;
+    private static final BitField _left_border_palette_idx  = bf(0x007F);
+    private static final BitField _right_border_palette_idx = bf(0x3F80);
+    private static final BitField _diag                     = bf(0xC000);
 
     // field_8_adtl_palette_options bit map
-    private static final BitField _top_border_palette_idx    =
-        BitFieldFactory.getInstance(0x0000007F);
-    private static final BitField _bottom_border_palette_idx =
-        BitFieldFactory.getInstance(0x00003F80);
-    private static final BitField _adtl_diag                 =
-        BitFieldFactory.getInstance(0x001fc000);
-    private static final BitField _adtl_diag_line_style      =
-        BitFieldFactory.getInstance(0x01e00000);
+    private static final BitField _top_border_palette_idx    = bf(0x0000007F);
+    private static final BitField _bottom_border_palette_idx = bf(0x00003F80);
+    private static final BitField _adtl_diag                 = bf(0x001fc000);
+    private static final BitField _adtl_diag_line_style      = bf(0x01e00000);
 
     // apparently bit 25 is unused
-    private static final BitField _adtl_fill_pattern         =
-        BitFieldFactory.getInstance(0xfc000000);
-    private int                   field_8_adtl_palette_options;   // 
additional to avoid 2
+    private static final BitField _adtl_fill_pattern         = bf(0xfc000000);
 
     // field_9_fill_palette_options bit map
-    private static final BitField _fill_foreground = 
BitFieldFactory.getInstance(0x007F);
-    private static final BitField _fill_background = 
BitFieldFactory.getInstance(0x3f80);
+    private static final BitField _fill_foreground = bf(0x007F);
+    private static final BitField _fill_background = bf(0x3f80);
+
+    private static BitField bf(int i) {
+        return BitFieldFactory.getInstance(i);
+    }
+
+
+    // fields in BOTH style and Cell XF records
+    private short field_1_font_index;             // not bit-mapped
+    private short field_2_format_index;           // not bit-mapped
+
+    private short field_3_cell_options;
+    private short field_4_alignment_options;
+    private short field_5_indention_options;
+    private short field_6_border_options;
+    private short field_7_palette_options;
+    private int   field_8_adtl_palette_options;   // additional to avoid 2
+
 
     // apparently bits 15 and 14 are unused
-    private short                 field_9_fill_palette_options;
+    private short field_9_fill_palette_options;
 
-    /**
-     * Constructor ExtendedFormatRecord
-     *
-     *
-     */
+    public ExtendedFormatRecord() {}
 
-    public ExtendedFormatRecord()
-    {
+    public ExtendedFormatRecord(ExtendedFormatRecord other) {
+        super(other);
+        field_1_font_index           = other.field_1_font_index;
+        field_2_format_index         = other.field_2_format_index;
+        field_3_cell_options         = other.field_3_cell_options;
+        field_4_alignment_options    = other.field_4_alignment_options;
+        field_5_indention_options    = other.field_5_indention_options;
+        field_6_border_options       = other.field_6_border_options;
+        field_7_palette_options      = other.field_7_palette_options;
+        field_8_adtl_palette_options = other.field_8_adtl_palette_options;
+        field_9_fill_palette_options = other.field_9_fill_palette_options;
     }
 
-    public ExtendedFormatRecord(RecordInputStream in)
-    {
+    public ExtendedFormatRecord(RecordInputStream in) {
         field_1_font_index           = in.readShort();
         field_2_format_index         = in.readShort();
         field_3_cell_options         = in.readShort();
@@ -560,7 +545,7 @@ public final class ExtendedFormatRecord
     /**
      * <p>Sets whether or not to use the pattern in this XF instead of the
      * parent XF (foreground/background).</p>
-     * 
+     *
      * @param pattern {@code true} if this XF has a different pattern
      *        value than its parent, {@code false} otherwise.
      * @see #setIndentionOptions(short)
@@ -1788,16 +1773,16 @@ public final class ExtendedFormatRecord
     {
         return sid;
     }
-    
+
     /**
      * Clones all the style information from another
-     *  ExtendedFormatRecord, onto this one. This 
+     *  ExtendedFormatRecord, onto this one. This
      *  will then hold all the same style options.
-     *  
+     *
      * If The source ExtendedFormatRecord comes from
      *  a different Workbook, you will need to sort
      *  out the font and format indices yourself!
-     * 
+     *
      * @param source the ExtendedFormatRecord to copy from
      */
     public void cloneStyleFrom(ExtendedFormatRecord source) {
@@ -1863,11 +1848,15 @@ public final class ExtendedFormatRecord
                }
                return false;
        }
-       
+
        public int[] stateSummary() {
                return new int[] { field_1_font_index, field_2_format_index, 
field_3_cell_options, field_4_alignment_options,
                                field_5_indention_options, 
field_6_border_options, field_7_palette_options, field_8_adtl_palette_options, 
field_9_fill_palette_options };
        }
-    
-    
+
+
+    @Override
+    public ExtendedFormatRecord copy() {
+        return new ExtendedFormatRecord(this);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ExternSheetRecord.java Sun 
Dec 22 21:44:45 2019
@@ -28,9 +28,9 @@ import org.apache.poi.util.LittleEndianO
  */
 public class ExternSheetRecord extends StandardRecord {
 
-    public final static short sid = 0x0017;
-       private final List<RefSubRecord> _list;
-       
+    public static final short sid = 0x0017;
+       private final List<RefSubRecord> _list = new ArrayList<>();
+
        private static final class RefSubRecord {
                public static final int ENCODED_SIZE = 6;
 
@@ -38,26 +38,31 @@ public class ExternSheetRecord extends S
                private final int _extBookIndex;
                private int _firstSheetIndex; // may be -1 (0xFFFF)
                private int _lastSheetIndex;  // may be -1 (0xFFFF)
-               
-               public void adjustIndex(int offset) {
-                       _firstSheetIndex += offset;
-                       _lastSheetIndex += offset;
-               }
-               
-               /** a Constructor for making new sub record
-                */
+
                public RefSubRecord(int extBookIndex, int firstSheetIndex, int 
lastSheetIndex) {
                        _extBookIndex = extBookIndex;
                        _firstSheetIndex = firstSheetIndex;
                        _lastSheetIndex = lastSheetIndex;
                }
-               
+
+               public RefSubRecord(RefSubRecord other) {
+                       _extBookIndex = other._extBookIndex;
+                       _firstSheetIndex = other._firstSheetIndex;
+                       _lastSheetIndex = other._lastSheetIndex;
+               }
+
                /**
                 * @param in the RecordInputstream to read the record from
                 */
                public RefSubRecord(RecordInputStream in) {
                        this(in.readShort(), in.readShort(), in.readShort());
                }
+
+               public void adjustIndex(int offset) {
+                       _firstSheetIndex += offset;
+                       _lastSheetIndex += offset;
+               }
+
                public int getExtBookIndex(){
                        return _extBookIndex;
                }
@@ -67,7 +72,7 @@ public class ExternSheetRecord extends S
                public int getLastSheetIndex(){
                        return _lastSheetIndex;
                }
-               
+
                @Override
                public String toString() {
                        StringBuilder buffer = new StringBuilder();
@@ -76,55 +81,53 @@ public class ExternSheetRecord extends S
                        buffer.append(" lastSheet=").append(_lastSheetIndex);
                        return buffer.toString();
                }
-               
+
                public void serialize(LittleEndianOutput out) {
                        out.writeShort(_extBookIndex);
                        out.writeShort(_firstSheetIndex);
                        out.writeShort(_lastSheetIndex);
                }
-       }       
-       
-       
-       
-       public ExternSheetRecord() {
-               _list = new ArrayList<>();
+       }
+
+       public ExternSheetRecord() {}
+
+       public ExternSheetRecord(ExternSheetRecord other) {
+               other._list.stream().map(RefSubRecord::new).forEach(_list::add);
        }
 
        public ExternSheetRecord(RecordInputStream in) {
-               _list = new ArrayList<>();
-               
                int nItems  = in.readShort();
-               
+
                for (int i = 0 ; i < nItems ; ++i) {
                        RefSubRecord rec = new RefSubRecord(in);
                        _list.add(rec);
                }
        }
-       
 
-       /**  
+
+       /**
         * @return number of REF structures
         */
        public int getNumOfRefs() {
                return _list.size();
        }
-       
-       /** 
+
+       /**
         * adds REF struct (ExternSheetSubRecord)
         * @param rec REF struct
         */
        public void addREFRecord(RefSubRecord rec) {
                _list.add(rec);
        }
-       
+
        /** returns the number of REF Records, which is in model
         * @return number of REF records
         */
        public int getNumOfREFRecords() {
                return _list.size();
        }
-       
-       
+
+
        @Override
        public String toString() {
                StringBuilder sb = new StringBuilder();
@@ -137,22 +140,22 @@ public class ExternSheetRecord extends S
                        sb.append('\n');
                }
                sb.append("[/EXTERNSHEET]\n");
-               
-               
+
+
                return sb.toString();
        }
-       
+
        @Override
        protected int getDataSize() {
                return 2 + _list.size() * RefSubRecord.ENCODED_SIZE;
        }
-       
+
        @Override
        public void serialize(LittleEndianOutput out) {
                int nItems = _list.size();
 
                out.writeShort(nItems);
-               
+
                for (int i = 0; i < nItems; i++) {
                        getRef(i).serialize(out);
                }
@@ -161,22 +164,22 @@ public class ExternSheetRecord extends S
        private RefSubRecord getRef(int i) {
                return _list.get(i);
        }
-       
+
        public void removeSheet(int sheetIdx) {
         int nItems = _list.size();
         for (int i = 0; i < nItems; i++) {
             RefSubRecord refSubRecord = _list.get(i);
-            if(refSubRecord.getFirstSheetIndex() == sheetIdx && 
+            if(refSubRecord.getFirstSheetIndex() == sheetIdx &&
                     refSubRecord.getLastSheetIndex() == sheetIdx) {
                // removing the entry would mess up the sheet index in Formula 
of NameRecord
                _list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), 
-1, -1));
-            } else if (refSubRecord.getFirstSheetIndex() > sheetIdx && 
+            } else if (refSubRecord.getFirstSheetIndex() > sheetIdx &&
                     refSubRecord.getLastSheetIndex() > sheetIdx) {
                 _list.set(i, new RefSubRecord(refSubRecord.getExtBookIndex(), 
refSubRecord.getFirstSheetIndex()-1, refSubRecord.getLastSheetIndex()-1));
             }
         }
        }
-       
+
        /**
         * return the non static version of the id for this record.
         */
@@ -187,7 +190,7 @@ public class ExternSheetRecord extends S
 
     /**
      * @param refIndex specifies the n-th refIndex
-     * 
+     *
      * @return the index of the SupBookRecord for this index
      */
     public int getExtbookIndexFromRefIndex(int refIndex) {
@@ -197,7 +200,7 @@ public class ExternSheetRecord extends S
 
        /**
         * @param extBookIndex external sheet reference index
-        * 
+        *
         * @return -1 if not found
         */
        public int findRefIndexFromExtBookIndex(int extBookIndex) {
@@ -214,9 +217,9 @@ public class ExternSheetRecord extends S
      * Returns the first sheet that the reference applies to, or
      *  -1 if the referenced sheet can't be found, or -2 if the
      *  reference is workbook scoped.
-     *  
+     *
      * @param extRefIndex external sheet reference index
-     * 
+     *
      * @return the first sheet that the reference applies to, or
      *  -1 if the referenced sheet can't be found, or -2 if the
      *  reference is workbook scoped
@@ -231,9 +234,9 @@ public class ExternSheetRecord extends S
      *  reference is workbook scoped.
      * For a single sheet reference, the first and last should be
      *  the same.
-     *  
+     *
      * @param extRefIndex external sheet reference index
-     * 
+     *
      * @return the last sheet that the reference applies to, or
      *  -1 if the referenced sheet can't be found, or -2 if the
      *  reference is workbook scoped.
@@ -258,7 +261,7 @@ public class ExternSheetRecord extends S
      *    see {@link org.apache.poi.hssf.record.SupBookRecord#getSheetNames()}.
      *    This referenced string specifies the name of the first sheet within 
the external workbook that is in scope.
      *    This sheet MUST be a worksheet or macro sheet.</p>
-     *    
+     *
      *    <p>If the supporting link type is self-referencing, then this value 
specifies the zero-based index of a
      *    {@link org.apache.poi.hssf.record.BoundSheetRecord} record in the 
workbook stream that specifies
      *    the first sheet within the scope of this reference. This sheet MUST 
be a worksheet or a macro sheet.
@@ -283,7 +286,7 @@ public class ExternSheetRecord extends S
                        if (ref.getExtBookIndex() != externalBookIndex) {
                                continue;
                        }
-                       if (ref.getFirstSheetIndex() == firstSheetIndex && 
+                       if (ref.getFirstSheetIndex() == firstSheetIndex &&
                                ref.getLastSheetIndex() == lastSheetIndex) {
                                return i;
                        }
@@ -301,4 +304,9 @@ public class ExternSheetRecord extends S
                }
                return result;
        }
+
+       @Override
+       public ExternSheetRecord copy() {
+               return new ExternSheetRecord(this);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ExternalNameRecord.java Sun 
Dec 22 21:44:45 2019
@@ -28,7 +28,7 @@ import org.apache.poi.util.StringUtil;
  */
 public final class ExternalNameRecord extends StandardRecord {
 
-       public final static short sid = 0x0023; // as per BIFF8. (some old 
versions used 0x223)
+       public static final short sid = 0x0023; // as per BIFF8. (some old 
versions used 0x223)
 
        private static final int OPT_BUILTIN_NAME          = 0x0001;
        private static final int OPT_AUTOMATIC_LINK        = 0x0002; // m$ doc 
calls this fWantAdvise
@@ -39,11 +39,11 @@ public final class ExternalNameRecord ex
        private static final int OPT_ICONIFIED_PICTURE_LINK= 0x8000;
 
 
-       private short  field_1_option_flag;
-       private short  field_2_ixals;
-       private short  field_3_not_used;
+       private short field_1_option_flag;
+       private short field_2_ixals;
+       private short field_3_not_used;
        private String field_4_name;
-       private Formula  field_5_name_definition;
+       private Formula field_5_name_definition;
 
        /**
         * 'rgoper' / 'Last received results of the DDE link'
@@ -60,6 +60,54 @@ public final class ExternalNameRecord ex
         */
        private int _nRows;
 
+       public ExternalNameRecord() {
+               field_2_ixals = 0;
+       }
+
+       public ExternalNameRecord(ExternalNameRecord other) {
+               super(other);
+               field_1_option_flag = other.field_1_option_flag;
+               field_2_ixals = other.field_2_ixals;
+               field_3_not_used = other.field_3_not_used;
+               field_4_name = other.field_4_name;
+               field_5_name_definition = (other.field_5_name_definition == 
null) ? null : other.field_5_name_definition.copy();
+               _ddeValues = (other._ddeValues == null) ? null : 
other._ddeValues.clone();
+               _nColumns = other._nColumns;
+               _nRows = other._nRows;
+       }
+
+       public ExternalNameRecord(RecordInputStream in) {
+               field_1_option_flag = in.readShort();
+               field_2_ixals       = in.readShort();
+               field_3_not_used    = in.readShort();
+
+               int numChars = in.readUByte();
+               field_4_name = StringUtil.readUnicodeString(in, numChars);
+
+               // the record body can take different forms.
+               // The form is dictated by the values of 3-th and 4-th bits in 
field_1_option_flag
+               if(!isOLELink() && !isStdDocumentNameIdentifier()){
+                       // another switch: the fWantAdvise bit specifies 
whether the body describes
+                       // an external defined name or a DDE data item
+                       if(isAutomaticLink()){
+                               if(in.available() > 0) {
+                                       //body specifies DDE data item
+                                       int nColumns = in.readUByte() + 1;
+                                       int nRows = in.readShort() + 1;
+
+                                       int totalCount = nRows * nColumns;
+                                       _ddeValues = 
ConstantValueParser.parse(in, totalCount);
+                                       _nColumns = nColumns;
+                                       _nRows = nRows;
+                               }
+                       } else {
+                               //body specifies an external defined name
+                               int formulaLen = in.readUShort();
+                               field_5_name_definition = 
Formula.read(formulaLen, in);
+                       }
+               }
+       }
+
        /**
         * @return {@code true} if the name is a built-in name
         */
@@ -68,7 +116,7 @@ public final class ExternalNameRecord ex
        }
        /**
         * For OLE and DDE, links can be either 'automatic' or 'manual'
-        * 
+        *
         * @return {@code true} if this is a automatic link
         */
        public boolean isAutomaticLink() {
@@ -76,7 +124,7 @@ public final class ExternalNameRecord ex
        }
        /**
         * only for OLE and DDE
-        * 
+        *
         * @return {@code true} if this is a picture link
         */
        public boolean isPicureLink() {
@@ -84,7 +132,7 @@ public final class ExternalNameRecord ex
        }
        /**
         * DDE links only. If <code>true</code>, this denotes the 
'StdDocumentName'
-        * 
+        *
         * @return {@code true} if this denotes the 'StdDocumentName'
         */
        public boolean isStdDocumentNameIdentifier() {
@@ -102,7 +150,7 @@ public final class ExternalNameRecord ex
        public String getText() {
                return field_4_name;
        }
-       
+
     public void setText(String str) {
         field_4_name = str;
     }
@@ -112,13 +160,13 @@ public final class ExternalNameRecord ex
         *  index of the name of the Sheet this refers to, as
         *  defined in the preceding {@link SupBookRecord}.
         * If it isn't a local name, then it must be zero.
-        * 
+        *
         * @return the index of the name of the Sheet this refers to
         */
        public short getIx() {
           return field_2_ixals;
        }
-       
+
     public void setIx(short ix) {
         field_2_ixals = ix;
     }
@@ -134,7 +182,7 @@ public final class ExternalNameRecord ex
        @Override
        protected int getDataSize(){
                int result = 2 + 4;  // short and int
-        result += StringUtil.getEncodedSize(field_4_name) - 1; //size is byte, 
not short 
+        result += StringUtil.getEncodedSize(field_4_name) - 1; //size is byte, 
not short
 
         if(!isOLELink() && !isStdDocumentNameIdentifier()){
             if(isAutomaticLink()){
@@ -171,42 +219,6 @@ public final class ExternalNameRecord ex
         }
        }
 
-    public ExternalNameRecord() {
-        field_2_ixals = 0;
-    }
-    
-    public ExternalNameRecord(RecordInputStream in) {
-               field_1_option_flag = in.readShort();
-               field_2_ixals       = in.readShort();
-      field_3_not_used    = in.readShort();
-
-        int numChars = in.readUByte();
-        field_4_name = StringUtil.readUnicodeString(in, numChars);
-
-        // the record body can take different forms.
-        // The form is dictated by the values of 3-th and 4-th bits in 
field_1_option_flag
-        if(!isOLELink() && !isStdDocumentNameIdentifier()){
-            // another switch: the fWantAdvise bit specifies whether the body 
describes
-            // an external defined name or a DDE data item
-            if(isAutomaticLink()){
-                if(in.available() > 0) {
-                   //body specifies DDE data item
-                   int nColumns = in.readUByte() + 1;
-                   int nRows = in.readShort() + 1;
-   
-                   int totalCount = nRows * nColumns;
-                   _ddeValues = ConstantValueParser.parse(in, totalCount);
-                   _nColumns = nColumns;
-                   _nRows = nRows;
-                }
-            } else {
-                //body specifies an external defined name
-                int formulaLen = in.readUShort();
-                field_5_name_definition = Formula.read(formulaLen, in);
-            }
-        }
-    }
-
        @Override
        public short getSid() {
                return sid;
@@ -228,4 +240,9 @@ public final class ExternalNameRecord ex
                sb.append("[/EXTERNALNAME]\n");
                return sb.toString();
        }
+
+       @Override
+       public ExternalNameRecord copy() {
+               return new ExternalNameRecord(this);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FeatHdrRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FeatHdrRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FeatHdrRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FeatHdrRecord.java Sun Dec 22 
21:44:45 2019
@@ -19,29 +19,30 @@ package org.apache.poi.hssf.record;
 
 import org.apache.poi.hssf.record.common.FtrHeader;
 import org.apache.poi.util.LittleEndianOutput;
+import org.apache.poi.util.Removal;
 
 /**
  * Title: FeatHdr (Feature Header) Record
  * <P>
- * This record specifies common information for Shared Features, and 
- *  specifies the beginning of a collection of records to define them. 
- * The collection of data (Globals Substream ABNF, macro sheet substream 
+ * This record specifies common information for Shared Features, and
+ *  specifies the beginning of a collection of records to define them.
+ * The collection of data (Globals Substream ABNF, macro sheet substream
  *  ABNF or worksheet substream ABNF) specifies Shared Feature data.
  */
-public final class FeatHdrRecord extends StandardRecord implements Cloneable  {
+public final class FeatHdrRecord extends StandardRecord {
        /**
-        * Specifies the enhanced protection type. Used to protect a 
-        * shared workbook by restricting access to some areas of it 
+        * Specifies the enhanced protection type. Used to protect a
+        * shared workbook by restricting access to some areas of it
         */
        public static final int SHAREDFEATURES_ISFPROTECTION = 0x02;
        /**
-        * Specifies that formula errors should be ignored 
+        * Specifies that formula errors should be ignored
         */
        public static final int SHAREDFEATURES_ISFFEC2       = 0x03;
        /**
         * Specifies the smart tag type. Recognises certain
         * types of entries (proper names, dates/times etc) and
-        * flags them for action 
+        * flags them for action
         */
        public static final int SHAREDFEATURES_ISFFACTOID    = 0x04;
        /**
@@ -50,13 +51,13 @@ public final class FeatHdrRecord extends
         */
        public static final int SHAREDFEATURES_ISFLIST       = 0x05;
 
-       
-       public final static short sid = 0x0867;
 
-       private FtrHeader futureHeader;
+       public static final short sid = 0x0867;
+
+       private final FtrHeader futureHeader;
        private int isf_sharedFeatureType; // See SHAREDFEATURES_
        private byte reserved; // Should always be one
-       /** 
+       /**
         * 0x00000000 = rgbHdrData not present
         * 0xffffffff = rgbHdrData present
         */
@@ -69,13 +70,18 @@ public final class FeatHdrRecord extends
                futureHeader.setRecordType(sid);
        }
 
-       public short getSid() {
-               return sid;
+       public FeatHdrRecord(FeatHdrRecord other) {
+               super(other);
+               futureHeader = other.futureHeader.copy();
+               isf_sharedFeatureType = other.isf_sharedFeatureType;
+               reserved = other.reserved;
+               cbHdrData = other.cbHdrData;
+               rgbHdrData = (other.rgbHdrData == null) ? null : 
other.rgbHdrData.clone();
        }
 
        public FeatHdrRecord(RecordInputStream in) {
                futureHeader = new FtrHeader(in);
-               
+
                isf_sharedFeatureType = in.readShort();
                reserved = in.readByte();
                cbHdrData = in.readInt();
@@ -83,19 +89,23 @@ public final class FeatHdrRecord extends
                rgbHdrData = in.readRemainder();
        }
 
+       public short getSid() {
+               return sid;
+       }
+
        public String toString() {
                StringBuilder buffer = new StringBuilder();
                buffer.append("[FEATURE HEADER]\n");
-               
+
                // TODO ...
-               
+
                buffer.append("[/FEATURE HEADER]\n");
                return buffer.toString();
        }
 
        public void serialize(LittleEndianOutput out) {
                futureHeader.serialize(out);
-               
+
                out.writeShort(isf_sharedFeatureType);
                out.writeByte(reserved);
                out.writeInt((int)cbHdrData);
@@ -105,12 +115,20 @@ public final class FeatHdrRecord extends
        protected int getDataSize() {
                return 12 + 2+1+4+rgbHdrData.length;
        }
-    
+
+       @Override
+       @SuppressWarnings("squid:S2975")
+       @Deprecated
+       @Removal(version = "5.0.0")
+       public FeatHdrRecord clone() {
+               return copy();
+       }
+
        @Override
-    public FeatHdrRecord clone() {
+    public FeatHdrRecord copy() {
            //HACK: do a "cheat" clone, see Record.java for more information
-        return (FeatHdrRecord)cloneViaReserialise();
+        return new FeatHdrRecord(this);
     }
 
-    
+
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FeatRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FeatRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FeatRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FeatRecord.java Sun Dec 22 
21:44:45 2019
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.stream.Stream;
+
 import org.apache.poi.hssf.record.common.FeatFormulaErr2;
 import org.apache.poi.hssf.record.common.FeatProtection;
 import org.apache.poi.hssf.record.common.FeatSmartTag;
@@ -26,6 +28,7 @@ import org.apache.poi.ss.util.CellRangeA
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Removal;
 
 /**
  * Title: Feat (Feature) Record
@@ -33,19 +36,17 @@ import org.apache.poi.util.POILogger;
  * This record specifies Shared Features data. It is normally paired
  *  up with a {@link FeatHdrRecord}.
  */
-public final class FeatRecord extends StandardRecord implements Cloneable  {
-    private static POILogger logger = 
POILogFactory.getLogger(FeatRecord.class);
-    public final static short sid = 0x0868;
+public final class FeatRecord extends StandardRecord {
+    private static final POILogger logger = 
POILogFactory.getLogger(FeatRecord.class);
+    public static final short sid = 0x0868;
     // SIDs from newer versions
-    public final static short v11_sid = 0x0872;
-    public final static short v12_sid = 0x0878;
-       
-       private FtrHeader futureHeader;
-       
-       /**
-        * See SHAREDFEATURES_* on {@link FeatHdrRecord}
-        */
-       private int isf_sharedFeatureType; 
+    public static final short v11_sid = 0x0872;
+    public static final short v12_sid = 0x0878;
+
+       private final FtrHeader futureHeader;
+
+       /** See SHAREDFEATURES_* on {@link FeatHdrRecord} */
+       private int isf_sharedFeatureType;
        private byte reserved1; // Should always be zero
        private long reserved2; // Should always be zero
        /** Only matters if type is ISFFEC2 */
@@ -55,24 +56,33 @@ public final class FeatRecord extends St
 
        /**
         * Contents depends on isf_sharedFeatureType :
-        *  ISFPROTECTION -> FeatProtection 
+        *  ISFPROTECTION -> FeatProtection
         *  ISFFEC2       -> FeatFormulaErr2
         *  ISFFACTOID    -> FeatSmartTag
         */
-       private SharedFeature sharedFeature; 
-       
+       private SharedFeature sharedFeature;
+
        public FeatRecord() {
                futureHeader = new FtrHeader();
                futureHeader.setRecordType(sid);
        }
 
-       public short getSid() {
-               return sid;
+       public FeatRecord(FeatRecord other) {
+               super(other);
+               futureHeader = other.futureHeader.copy();
+               isf_sharedFeatureType = other.isf_sharedFeatureType;
+               reserved1 = other.reserved1;
+               reserved2 = other.reserved2;
+               cbFeatData = other.cbFeatData;
+               reserved3 = other.reserved3;
+               cellRefs = (other.cellRefs == null) ? null :
+                       
Stream.of(other.cellRefs).map(CellRangeAddress::copy).toArray(CellRangeAddress[]::new);
+               sharedFeature = (other.sharedFeature == null) ? null : 
other.sharedFeature.copy();
        }
 
        public FeatRecord(RecordInputStream in) {
                futureHeader = new FtrHeader(in);
-               
+
                isf_sharedFeatureType = in.readShort();
                reserved1 = in.readByte();
                reserved2 = in.readInt();
@@ -84,7 +94,7 @@ public final class FeatRecord extends St
                for(int i=0; i<cellRefs.length; i++) {
                        cellRefs[i] = new CellRangeAddress(in);
                }
-               
+
                switch(isf_sharedFeatureType) {
                case FeatHdrRecord.SHAREDFEATURES_ISFPROTECTION:
                        sharedFeature = new FeatProtection(in);
@@ -100,30 +110,34 @@ public final class FeatRecord extends St
                }
        }
 
+       public short getSid() {
+               return sid;
+       }
+
        public String toString() {
                StringBuilder buffer = new StringBuilder();
                buffer.append("[SHARED FEATURE]\n");
-               
+
                // TODO ...
-               
+
                buffer.append("[/SHARED FEATURE]\n");
                return buffer.toString();
        }
 
        public void serialize(LittleEndianOutput out) {
                futureHeader.serialize(out);
-               
+
                out.writeShort(isf_sharedFeatureType);
                out.writeByte(reserved1);
                out.writeInt((int)reserved2);
                out.writeShort(cellRefs.length);
                out.writeInt((int)cbFeatData);
                out.writeShort(reserved3);
-               
+
                for(int i=0; i<cellRefs.length; i++) {
                        cellRefs[i].serialize(out);
                }
-               
+
                sharedFeature.serialize(out);
        }
 
@@ -156,7 +170,7 @@ public final class FeatRecord extends St
        }
        public void setSharedFeature(SharedFeature feature) {
                this.sharedFeature = feature;
-               
+
                if(feature instanceof FeatProtection) {
                        isf_sharedFeatureType = 
FeatHdrRecord.SHAREDFEATURES_ISFPROTECTION;
                }
@@ -166,7 +180,7 @@ public final class FeatRecord extends St
                if(feature instanceof FeatSmartTag) {
                        isf_sharedFeatureType = 
FeatHdrRecord.SHAREDFEATURES_ISFFACTOID;
                }
-               
+
                if(isf_sharedFeatureType == 
FeatHdrRecord.SHAREDFEATURES_ISFFEC2) {
                        cbFeatData = sharedFeature.getDataSize();
                } else {
@@ -174,12 +188,16 @@ public final class FeatRecord extends St
                }
        }
 
-    
        @Override
+       @SuppressWarnings("squid:S2975")
+       @Deprecated
+       @Removal(version = "5.0.0")
        public FeatRecord clone() {
-        //HACK: do a "cheat" clone, see Record.java for more information
-        return (FeatRecord)cloneViaReserialise();
-    }
+               return copy();
+       }
 
-    
+       @Override
+       public FeatRecord copy() {
+        return new FeatRecord(this);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java?rev=1871911&r1=1871910&r2=1871911&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java Sun Dec 
22 21:44:45 2019
@@ -33,13 +33,14 @@ import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianByteArrayOutputStream;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.LittleEndianOutputStream;
+import org.apache.poi.util.Removal;
 
 /**
- * Title: File Pass Record (0x002F) <p>
+ * File Pass Record (0x002F) <p>
  *
- * Description: Indicates that the record after this record are encrypted.
+ * Indicates that the record after this record are encrypted.
  */
-public final class FilePassRecord extends StandardRecord implements Cloneable {
+public final class FilePassRecord extends StandardRecord {
        public static final short sid = 0x002F;
     private static final int ENCRYPTION_XOR = 0;
     private static final int ENCRYPTION_OTHER = 1;
@@ -48,12 +49,9 @@ public final class FilePassRecord extend
     private EncryptionInfo encryptionInfo;
 
        private FilePassRecord(FilePassRecord other) {
+        super(other);
            encryptionType = other.encryptionType;
-        try {
-            encryptionInfo = other.encryptionInfo.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new EncryptedDocumentException(e);
-        }
+        encryptionInfo = other.encryptionInfo.copy();
        }
 
        public FilePassRecord(EncryptionMode encryptionMode) {
@@ -138,8 +136,16 @@ public final class FilePassRecord extend
                return sid;
        }
 
-       @Override
-       public FilePassRecord clone() {
+    @Override
+    @SuppressWarnings("squid:S2975")
+    @Deprecated
+    @Removal(version = "5.0.0")
+    public FilePassRecord clone() {
+        return copy();
+    }
+
+    @Override
+       public FilePassRecord copy() {
                return new FilePassRecord(this);
        }
 



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

Reply via email to