Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/FormulaSpecialCachedValue.java 
Sun Apr 12 22:03:52 2020
@@ -17,8 +17,15 @@
 
 package org.apache.poi.hssf.record;
 
+import static org.apache.poi.util.GenericRecordUtil.getEnumBitsAsString;
+
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndianOutput;
@@ -29,7 +36,7 @@ import org.apache.poi.util.LittleEndianO
  * values that are decoded/encoded by this class.
  */
 @Internal
-public final class FormulaSpecialCachedValue {
+public final class FormulaSpecialCachedValue implements GenericRecord {
     /** deliberately chosen by Excel in order to encode other values within 
Double NaNs */
     private static final long BIT_MARKER = 0xFFFF000000000000L;
     private static final int VARIABLE_DATA_LENGTH = 6;
@@ -164,4 +171,29 @@ public final class FormulaSpecialCachedV
         }
         return getDataValue();
     }
+
+    private Object getGenericValue() {
+        int typeCode = getTypeCode();
+        switch (typeCode) {
+            case EMPTY: // is this correct?
+                return null;
+            case STRING:
+                return "string";
+            case BOOLEAN:
+                return getBooleanValue();
+            case ERROR_CODE:
+                return getErrorValue();
+        }
+        throw new IllegalStateException("Unexpected type id (" + typeCode + 
")");
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "value", this::getGenericValue,
+            "typeCode", getEnumBitsAsString(this::getTypeCode,
+                new int[]{STRING,BOOLEAN,ERROR_CODE,EMPTY},
+                new String[]{"STRING","BOOLEAN","ERROR_CODE","EMPTY"})
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FtCblsSubRecord.java Sun Apr 
12 22:03:52 2020
@@ -17,7 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
@@ -48,6 +51,10 @@ public final class FtCblsSubRecord exten
     }
 
     public FtCblsSubRecord(LittleEndianInput in, int size) {
+        this(in,size,-1);
+    }
+
+    FtCblsSubRecord(LittleEndianInput in, int size, int cmoOt) {
         if (size != ENCODED_SIZE) {
             throw new RecordFormatException("Unexpected size (" + size + ")");
         }
@@ -58,21 +65,6 @@ public final class FtCblsSubRecord exten
     }
 
     /**
-     * Convert this record to string.
-     * Used by BiffViewer and other utilities.
-     */
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[FtCbls ]").append("\n");
-        buffer.append("  size     = ").append(getDataSize()).append("\n");
-        buffer.append("  reserved = 
").append(HexDump.toHex(reserved)).append("\n");
-        buffer.append("[/FtCbls ]").append("\n");
-        return buffer.toString();
-    }
-
-    /**
      * Serialize the record data into the supplied array of bytes
      *
      * @param out the stream to serialize into
@@ -108,4 +100,13 @@ public final class FtCblsSubRecord exten
         return new FtCblsSubRecord(this);
     }
 
+    @Override
+    public SubRecordTypes getGenericRecordType() {
+        return SubRecordTypes.FT_CBLS;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("reserved", () -> 
reserved);
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FtCfSubRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,7 +17,12 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import static org.apache.poi.util.GenericRecordUtil.getEnumBitsAsString;
+
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
@@ -61,6 +66,10 @@ public final class FtCfSubRecord extends
     }
 
     public FtCfSubRecord(LittleEndianInput in, int size) {
+        this(in,size,-1);
+    }
+
+    FtCfSubRecord(LittleEndianInput in, int size, int cmoOt) {
         if (size != length) {
             throw new RecordFormatException("Unexpected size (" + size + ")");
         }
@@ -68,19 +77,6 @@ public final class FtCfSubRecord extends
     }
 
     /**
-     * Convert this record to string.
-     * Used by BiffViewer and other utilities.
-     */
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append("[FtCf ]\n");
-        buffer.append("  size     = ").append(length).append("\n");
-        buffer.append("  flags    = 
").append(HexDump.toHex(flags)).append("\n");
-        buffer.append("[/FtCf ]\n");
-        return buffer.toString();
-    }
-
-    /**
      * Serialize the record data into the supplied array of bytes
      *
      * @param out the stream to serialize into
@@ -116,11 +112,23 @@ public final class FtCfSubRecord extends
         return new FtCfSubRecord(this);
     }
 
- public short getFlags() {
-   return flags;
- }
-
- public void setFlags(short flags) {
-   this.flags = flags;
- }
+    public short getFlags() {
+        return flags;
+    }
+
+    public void setFlags(short flags) {
+        this.flags = flags;
+    }
+
+    @Override
+    public SubRecordTypes getGenericRecordType() {
+        return SubRecordTypes.FT_CF;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("flags", 
getEnumBitsAsString(this::getFlags,
+            new int[]{METAFILE_BIT,BITMAP_BIT,UNSPECIFIED_BIT},
+            new String[]{"METAFILE","BITMAP","UNSPECIFIED"}));
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FtPioGrbitSubRecord.java Sun 
Apr 12 22:03:52 2020
@@ -17,7 +17,12 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
+
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
@@ -98,6 +103,10 @@ public final class FtPioGrbitSubRecord e
     }
 
     public FtPioGrbitSubRecord(LittleEndianInput in, int size) {
+        this(in,size,-1);
+    }
+
+    FtPioGrbitSubRecord(LittleEndianInput in, int size, int cmoOt) {
         if (size != length) {
             throw new RecordFormatException("Unexpected size (" + size + ")");
         }
@@ -122,19 +131,6 @@ public final class FtPioGrbitSubRecord e
     }
 
     /**
-     * Convert this record to string.
-     * Used by BiffViewer and other utilities.
-     */
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append("[FtPioGrbit ]\n");
-        buffer.append("  size     = ").append(length).append("\n");
-        buffer.append("  flags    = 
").append(HexDump.toHex(flags)).append("\n");
-        buffer.append("[/FtPioGrbit ]\n");
-        return buffer.toString();
-    }
-
-    /**
      * Serialize the record data into the supplied array of bytes
      *
      * @param out the stream to serialize into
@@ -170,11 +166,25 @@ public final class FtPioGrbitSubRecord e
         return new FtPioGrbitSubRecord(this);
     }
 
- public short getFlags() {
-   return flags;
- }
-
- public void setFlags(short flags) {
-   this.flags = flags;
- }
+    public short getFlags() {
+        return flags;
+    }
+
+    public void setFlags(short flags) {
+        this.flags = flags;
+    }
+
+    @Override
+    public SubRecordTypes getGenericRecordType() {
+        return SubRecordTypes.FT_PIO_GRBIT;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "flags", getBitsAsString(this::getFlags,
+            new int[]{AUTO_PICT_BIT, DDE_BIT, PRINT_CALC_BIT, ICON_BIT, 
CTL_BIT, PRSTM_BIT, CAMERA_BIT, DEFAULT_SIZE_BIT, AUTO_LOAD_BIT},
+            new String[]{"AUTO_PICT", "DDE", "PRINT_CALC", "ICON", "CTL", 
"PRSTM", "CAMERA", "DEFAULT_SIZE", "AUTO_LOAD"})
+        );
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/GridsetRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 ==================================================================== */
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -63,13 +67,6 @@ public final class GridsetRecord extends
         return (field_1_gridset_flag == 1);
     }
 
-    public String toString() {
-        return "[GRIDSET]\n" +
-                "    .gridset        = " + getGridset() +
-                "\n" +
-                "[/GRIDSET]\n";
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(field_1_gridset_flag);
     }
@@ -84,7 +81,7 @@ public final class GridsetRecord extends
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public GridsetRecord clone() {
@@ -95,4 +92,14 @@ public final class GridsetRecord extends
     public GridsetRecord copy() {
         return new GridsetRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.GRIDSET;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("gridset", 
this::getGridset);
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/GroupMarkerSubRecord.java Sun 
Apr 12 22:03:52 2020
@@ -17,7 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
@@ -48,22 +51,15 @@ public final class GroupMarkerSubRecord
     }
 
     public GroupMarkerSubRecord(LittleEndianInput in, int size) {
+        this(in,size,-1);
+    }
+
+    GroupMarkerSubRecord(LittleEndianInput in, int size, int cmoOt) {
         byte[] buf = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
         in.readFully(buf);
         reserved = buf;
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        String nl = System.getProperty("line.separator");
-        buffer.append("[ftGmo]" + nl);
-        buffer.append("  reserved = 
").append(HexDump.toHex(reserved)).append(nl);
-        buffer.append("[/ftGmo]" + nl);
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(sid);
         out.writeShort(reserved.length);
@@ -91,4 +87,15 @@ public final class GroupMarkerSubRecord
     public GroupMarkerSubRecord copy() {
         return new GroupMarkerSubRecord(this);
     }
+
+
+    @Override
+    public SubRecordTypes getGenericRecordType() {
+        return SubRecordTypes.GROUP_MARKER;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("reserved", () -> 
reserved);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/GutsRecord.java Sun Apr 12 
22:03:52 2020
@@ -19,6 +19,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -144,23 +148,6 @@ public final class GutsRecord extends St
         return field_4_col_level_max;
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[GUTS]\n");
-        buffer.append("    .leftgutter     = ")
-            .append(Integer.toHexString(getLeftRowGutter())).append("\n");
-        buffer.append("    .topgutter      = ")
-            .append(Integer.toHexString(getTopColGutter())).append("\n");
-        buffer.append("    .rowlevelmax    = ")
-            .append(Integer.toHexString(getRowLevelMax())).append("\n");
-        buffer.append("    .collevelmax    = ")
-            .append(Integer.toHexString(getColLevelMax())).append("\n");
-        buffer.append("[/GUTS]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(getLeftRowGutter());
         out.writeShort(getTopColGutter());
@@ -178,7 +165,7 @@ public final class GutsRecord extends St
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public GutsRecord clone() {
@@ -189,4 +176,19 @@ public final class GutsRecord extends St
     public GutsRecord copy() {
       return new GutsRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.GUTS;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "leftGutter", this::getLeftRowGutter,
+            "topGutter", this::getTopColGutter,
+            "rowLevelMax", this::getRowLevelMax,
+            "colLevelMax", this::getColLevelMax
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HCenterRecord.java Sun Apr 12 
22:03:52 2020
@@ -16,6 +16,10 @@
 ==================================================================== */
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -56,13 +60,6 @@ public final class HCenterRecord extends
         return (field_1_hcenter == 1);
     }
 
-    public String toString() {
-        return "[HCENTER]\n" +
-                "    .hcenter        = " + getHCenter() +
-                "\n" +
-                "[/HCENTER]\n";
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(field_1_hcenter);
     }
@@ -77,7 +74,7 @@ public final class HCenterRecord extends
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public HCenterRecord clone() {
@@ -86,6 +83,16 @@ public final class HCenterRecord extends
 
     @Override
     public HCenterRecord copy() {
-      return new HCenterRecord(this);
+        return new HCenterRecord(this);
+    }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.H_CENTER;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("hcenter", 
this::getHCenter);
     }
 }

Added: poi/trunk/src/java/org/apache/poi/hssf/record/HSSFRecordTypes.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HSSFRecordTypes.java?rev=1876433&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HSSFRecordTypes.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HSSFRecordTypes.java Sun Apr 
12 22:03:52 2020
@@ -0,0 +1,233 @@
+/*
+ *  ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one or more
+ *    contributor license agreements.  See the NOTICE file distributed with
+ *    this work for additional information regarding copyright ownership.
+ *    The ASF licenses this file to You under the Apache License, Version 2.0
+ *    (the "License"); you may not use this file except in compliance with
+ *    the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ * ====================================================================
+ */
+
+package org.apache.poi.hssf.record;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.hssf.record.chart.*;
+import org.apache.poi.hssf.record.pivottable.DataItemRecord;
+import 
org.apache.poi.hssf.record.pivottable.ExtendedPivotTableViewFieldsRecord;
+import org.apache.poi.hssf.record.pivottable.PageItemRecord;
+import org.apache.poi.hssf.record.pivottable.StreamIDRecord;
+import org.apache.poi.hssf.record.pivottable.ViewDefinitionRecord;
+import org.apache.poi.hssf.record.pivottable.ViewFieldsRecord;
+import org.apache.poi.hssf.record.pivottable.ViewSourceRecord;
+
+public enum HSSFRecordTypes {
+    UNKNOWN(-1, UnknownRecord::new),
+    FORMULA(0x0006, FormulaRecord::new),
+    EOF(0x000A, EOFRecord::new),
+    CALC_COUNT(0x000C, CalcCountRecord::new),
+    CALC_MODE(0x000D, CalcModeRecord::new),
+    PRECISION(0x000E, PrecisionRecord::new),
+    REF_MODE(0x000F, RefModeRecord::new),
+    DELTA(0x0010, DeltaRecord::new),
+    ITERATION(0x0011, IterationRecord::new),
+    PROTECT(0x0012, ProtectRecord::new),
+    PASSWORD(0x0013, PasswordRecord::new),
+    HEADER(0x0014, HeaderRecord::new),
+    FOOTER(0x0015, FooterRecord::new),
+    EXTERN_SHEET(0x0017, ExternSheetRecord::new),
+    NAME(0x0018, NameRecord::new),
+    WINDOW_PROTECT(0x0019, WindowProtectRecord::new),
+    VERTICAL_PAGE_BREAK(0x001A, VerticalPageBreakRecord::new),
+    HORIZONTAL_PAGE_BREAK(0x001B, HorizontalPageBreakRecord::new),
+    NOTE(0x001C, NoteRecord::new),
+    SELECTION(0x001D, SelectionRecord::new),
+    DATE_WINDOW_1904(0x0022, DateWindow1904Record::new),
+    EXTERNAL_NAME(0x0023, ExternalNameRecord::new),
+    LEFT_MARGIN(0x0026, LeftMarginRecord::new),
+    RIGHT_MARGIN(0x0027, RightMarginRecord::new),
+    TOP_MARGIN(0x0028, TopMarginRecord::new),
+    BOTTOM_MARGIN(0x0029, BottomMarginRecord::new),
+    PRINT_HEADERS(0x002A, PrintHeadersRecord::new),
+    PRINT_GRIDLINES(0X002B, PrintGridlinesRecord::new),
+    FILE_PASS(0x002F, FilePassRecord::new),
+    FONT(0x0031, FontRecord::new),
+    CONTINUE(0x003C, ContinueRecord::new),
+    WINDOW_ONE(0x003D, WindowOneRecord::new),
+    BACKUP(0x0040, BackupRecord::new),
+    PANE(0x0041, PaneRecord::new),
+    CODEPAGE(0x0042, CodepageRecord::new),
+    DCON_REF(0x0051, DConRefRecord::new),
+    DEFAULT_COL_WIDTH(0x0055, DefaultColWidthRecord::new),
+    CRN_COUNT(0x0059, CRNCountRecord::new),
+    CRN(0x005A, CRNRecord::new),
+    WRITE_ACCESS(0x005C, WriteAccessRecord::new),
+    FILE_SHARING(0x005B, FileSharingRecord::new),
+    OBJ(0x005D, ObjRecord::new),
+    UNCALCED(0x005E, UncalcedRecord::new),
+    SAVE_RECALC(0x005F, SaveRecalcRecord::new),
+    OBJECT_PROTECT(0x0063, ObjectProtectRecord::new),
+    COLUMN_INFO(0x007D, ColumnInfoRecord::new),
+    GUTS(0x0080, GutsRecord::new),
+    WS_BOOL(0x0081, WSBoolRecord::new),
+    GRIDSET(0x0082, GridsetRecord::new),
+    H_CENTER(0x0083, HCenterRecord::new),
+    V_CENTER(0x0084, VCenterRecord::new),
+    BOUND_SHEET(0x0085, BoundSheetRecord::new),
+    WRITE_PROTECT(0x0086, WriteProtectRecord::new),
+    COUNTRY(0X008C, CountryRecord::new),
+    HIDE_OBJ(0x008D, HideObjRecord::new),
+    PALETTE(0x0092, PaletteRecord::new),
+    FN_GROUP_COUNT(0x009c, FnGroupCountRecord::new),
+    AUTO_FILTER_INFO(0x009D, AutoFilterInfoRecord::new),
+    SCL(0x00A0, SCLRecord::new),
+    PRINT_SETUP(0x00A1, PrintSetupRecord::new),
+    VIEW_DEFINITION(0x00B0, ViewDefinitionRecord::new),
+    VIEW_FIELDS(0x00B1, ViewFieldsRecord::new),
+    PAGE_ITEM(0x00B6, PageItemRecord::new),
+    MUL_BLANK(0x00BE, MulBlankRecord::new),
+    MUL_RK(0x00BD, MulRKRecord::new),
+    MMS(0x00C1, MMSRecord::new),
+    DATA_ITEM(0x00C5, DataItemRecord::new),
+    STREAM_ID(0x00D5, StreamIDRecord::new),
+    DB_CELL(0x00D7, DBCellRecord::new),
+    BOOK_BOOL(0x00DA, BookBoolRecord::new),
+    SCENARIO_PROTECT(0x00DD, ScenarioProtectRecord::new),
+    EXTENDED_FORMAT(0x00E0, ExtendedFormatRecord::new),
+    INTERFACE_HDR(0x00E1, InterfaceHdrRecord::new),
+    INTERFACE_END(0x00E2, InterfaceEndRecord::create),
+    VIEW_SOURCE(0x00E3, ViewSourceRecord::new),
+    MERGE_CELLS(0x00E5, MergeCellsRecord::new),
+    DRAWING_GROUP(0x00EB, DrawingGroupRecord::new),
+    DRAWING(0x00EC, DrawingRecord::new),
+    DRAWING_SELECTION(0x00ED, DrawingSelectionRecord::new),
+    SST(0x00FC, SSTRecord::new),
+    LABEL_SST(0X00FD, LabelSSTRecord::new),
+    EXT_SST(0x00FF, ExtSSTRecord::new),
+    EXTENDED_PIVOT_TABLE_VIEW_FIELDS(0x0100, 
ExtendedPivotTableViewFieldsRecord::new),
+    TAB_ID(0x013D, TabIdRecord::new),
+    USE_SEL_FS(0x0160, UseSelFSRecord::new),
+    DSF(0x0161, DSFRecord::new),
+    USER_SVIEW_BEGIN(0x01AA, UserSViewBegin::new),
+    USER_SVIEW_END(0x01AB, UserSViewEnd::new),
+    SUP_BOOK(0x01AE, SupBookRecord::new),
+    PROTECTION_REV_4(0x01AF, ProtectionRev4Record::new),
+    CF_HEADER(0x01B0, CFHeaderRecord::new),
+    CF_RULE(0x01B1, CFRuleRecord::new),
+    DVAL(0x01B2, DVALRecord::new),
+    TEXT_OBJECT(0x01B6, TextObjectRecord::new),
+    REFRESH_ALL(0x01B7, RefreshAllRecord::new),
+    HYPERLINK(0x01B8, HyperlinkRecord::new),
+    PASSWORD_REV_4(0x01BC, PasswordRev4Record::new),
+    DV(0x01BE, DVRecord::new),
+    RECALC_ID(0x01C1, RecalcIdRecord::new),
+    DIMENSIONS(0x0200, DimensionsRecord::new),
+    BLANK(0x0201, BlankRecord::new),
+    NUMBER(0x0203, NumberRecord::new),
+    LABEL(0x0204, LabelRecord::new),
+    BOOL_ERR(0x0205, BoolErrRecord::new),
+    STRING(0x0207, StringRecord::new),
+    ROW(0x0208, RowRecord::new),
+    INDEX(0x020B, IndexRecord::new),
+    ARRAY(0x0221, ArrayRecord::new),
+    DEFAULT_ROW_HEIGHT(0x0225, DefaultRowHeightRecord::new),
+    TABLE(0x0236, TableRecord::new),
+    WINDOW_TWO(0x023E, WindowTwoRecord::new),
+    RK(0x027E, RKRecord::new),
+    STYLE(0x0293, StyleRecord::new),
+    FORMAT(0x041E, FormatRecord::new),
+    SHARED_FORMULA(0x04BC, SharedFormulaRecord::new),
+    BOF(0x0809, BOFRecord::new),
+    CHART_FRT_INFO(0x0850, ChartFRTInfoRecord::new),
+    CHART_START_BLOCK(0x0852, ChartStartBlockRecord::new),
+    CHART_END_BLOCK(0x0853, ChartEndBlockRecord::new),
+    CHART_START_OBJECT(0x0854, ChartStartObjectRecord::new),
+    CHART_END_OBJECT(0x0855, ChartEndObjectRecord::new),
+    CAT_LAB(0x0856, CatLabRecord::new),
+    FEAT_HDR(0x0867, FeatHdrRecord::new),
+    FEAT(0x0868, FeatRecord::new),
+    DATA_LABEL_EXTENSION(0x086A, DataLabelExtensionRecord::new),
+    CF_HEADER_12(0x0879, CFHeader12Record::new),
+    CF_RULE_12(0x087A, CFRule12Record::new),
+    TABLE_STYLES(0x088E, TableStylesRecord::new),
+    NAME_COMMENT(0x0894, NameCommentRecord::new),
+    HEADER_FOOTER(0x089C, HeaderFooterRecord::new),
+    UNITS(0x1001, UnitsRecord::new),
+    CHART(0x1002, ChartRecord::new),
+    SERIES(0x1003, SeriesRecord::new),
+    DATA_FORMAT(0x1006, DataFormatRecord::new),
+    LINE_FORMAT(0x1007, LineFormatRecord::new),
+    AREA_FORMAT(0x100A, AreaFormatRecord::new),
+    SERIES_LABELS(0x100C, SeriesLabelsRecord::new),
+    SERIES_TEXT(0x100D, SeriesTextRecord::new),
+    CHART_FORMAT(0x1014, ChartFormatRecord::new),
+    LEGEND(0x1015, LegendRecord::new),
+    SERIES_LIST(0x1016, SeriesListRecord::new),
+    BAR(0x1017, BarRecord::new),
+    AREA(0x101A, AreaRecord::new),
+    AXIS(0x101D, AxisRecord::new),
+    TICK(0x101E, TickRecord::new),
+    VALUE_RANGE(0x101F, ValueRangeRecord::new),
+    CATEGORY_SERIES_AXIS(0x1020, CategorySeriesAxisRecord::new),
+    AXIS_LINE_FORMAT(0x1021, AxisLineFormatRecord::new),
+    DEFAULT_DATA_LABEL_TEXT_PROPERTIES(0x1024, 
DefaultDataLabelTextPropertiesRecord::new),
+    TEXT(0x1025, TextRecord::new),
+    FONT_INDEX(0x1026, FontIndexRecord::new),
+    OBJECT_LINK(0x1027, ObjectLinkRecord::new),
+    FRAME(0x1032, FrameRecord::new),
+    BEGIN(0x1033, BeginRecord::new),
+    END(0x1034, EndRecord::new),
+    PLOT_AREA(0x1035, PlotAreaRecord::new),
+    AXIS_PARENT(0x1041, AxisParentRecord::new),
+    SHEET_PROPERTIES(0x1044, SheetPropertiesRecord::new),
+    SERIES_CHART_GROUP_INDEX(0x1045, SeriesChartGroupIndexRecord::new),
+    AXIS_USED(0x1046, AxisUsedRecord::new),
+    NUMBER_FORMAT_INDEX(0x104E, NumberFormatIndexRecord::new),
+    CHART_TITLE_FORMAT(0x1050, ChartTitleFormatRecord::new),
+    LINKED_DATA(0x1051, LinkedDataRecord::new),
+    FONT_BASIS(0x1060, FontBasisRecord::new),
+    AXIS_OPTIONS(0x1062, AxisOptionsRecord::new),
+    DAT(0x1063, DatRecord::new),
+    PLOT_GROWTH(0x1064, PlotGrowthRecord::new),
+    SERIES_INDEX(0x1065, SeriesIndexRecord::new),
+    // Dummy record
+    ESCHER_AGGREGATE(9876, (in) -> new EscherAggregate(true))
+    ;
+
+    @FunctionalInterface
+    public interface RecordConstructor<T extends Record> {
+        T apply(RecordInputStream in);
+    }
+
+    private static final Map<Short,HSSFRecordTypes> LOOKUP;
+
+    static {
+        LOOKUP = new HashMap<>();
+        for(HSSFRecordTypes s : values()) {
+            LOOKUP.put(s.sid, s);
+        }
+    }
+
+    public final short sid;
+    public final RecordConstructor<?> recordConstructor;
+
+    HSSFRecordTypes(int sid, RecordConstructor<?> recordConstructor) {
+        this.sid = (short)sid;
+        this.recordConstructor = recordConstructor;
+    }
+
+    public static HSSFRecordTypes forTypeID(int typeID) {
+        return LOOKUP.getOrDefault((short)typeID, UNKNOWN);
+    }
+
+}

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

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterBase.java Sun Apr 
12 22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
@@ -114,4 +118,9 @@ public abstract class HeaderFooterBase e
 
        @Override
        public abstract HeaderFooterBase copy();
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties("text", 
this::getText);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HeaderFooterRecord.java Sun 
Apr 12 22:03:52 2020
@@ -18,9 +18,10 @@
 package org.apache.poi.hssf.record;
 
 import java.util.Arrays;
-import java.util.Locale;
+import java.util.Map;
+import java.util.function.Supplier;
 
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -29,6 +30,7 @@ import org.apache.poi.util.Removal;
  */
 public final class HeaderFooterRecord extends StandardRecord {
     public static final short sid = 0x089C;
+    @SuppressWarnings("MismatchedReadAndWriteOfArray")
     private static final byte[] BLANK_GUID = new byte[16];
 
        private byte[] _rawData;
@@ -88,15 +90,8 @@ public final class HeaderFooterRecord ex
         return Arrays.equals(getGuid(), BLANK_GUID);
     }
 
-    public String toString() {
-        return '[' + "HEADERFOOTER" + "] (0x" +
-                Integer.toHexString(sid).toUpperCase(Locale.ROOT) + ")\n" +
-                "  rawData=" + HexDump.toHex(_rawData) + "\n" +
-                "[/" + "HEADERFOOTER" + "]\n";
-    }
-
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public HeaderFooterRecord clone() {
@@ -108,5 +103,13 @@ public final class HeaderFooterRecord ex
         return new HeaderFooterRecord(this);
     }
 
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.HEADER_FOOTER;
+    }
 
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("rawData", () -> 
_rawData);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HeaderRecord.java Sun Apr 12 
22:03:52 2020
@@ -37,21 +37,12 @@ public final class HeaderRecord extends
                super(in);
        }
 
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[HEADER]\n");
-               buffer.append("    .header = ").append(getText()).append("\n");
-               buffer.append("[/HEADER]\n");
-               return buffer.toString();
-       }
-
        public short getSid() {
                return sid;
        }
 
        @Override
-       @SuppressWarnings("squid:S2975")
+       @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
        @Deprecated
        @Removal(version = "5.0.0")
        public HeaderRecord clone() {
@@ -62,4 +53,9 @@ public final class HeaderRecord extends
        public HeaderRecord copy() {
                return new HeaderRecord(this);
        }
+
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.HEADER;
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HideObjRecord.java Sun Apr 12 
22:03:52 2020
@@ -19,6 +19,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -73,17 +77,6 @@ public final class HideObjRecord extends
         return field_1_hide_obj;
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[HIDEOBJ]\n");
-        buffer.append("    .hideobj         = ")
-            .append(Integer.toHexString(getHideObj())).append("\n");
-        buffer.append("[/HIDEOBJ]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(getHideObj());
     }
@@ -101,4 +94,14 @@ public final class HideObjRecord extends
     public HideObjRecord copy() {
         return new HideObjRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.HIDE_OBJ;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("hideObj", 
this::getHideObj);
+    }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/hssf/record/HorizontalPageBreakRecord.java 
Sun Apr 12 22:03:52 2020
@@ -49,7 +49,7 @@ public final class HorizontalPageBreakRe
        }
 
        @Override
-       @SuppressWarnings("squid:S2975")
+       @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
        @Deprecated
        @Removal(version = "5.0.0")
        public PageBreakRecord clone() {
@@ -60,4 +60,9 @@ public final class HorizontalPageBreakRe
        public HorizontalPageBreakRecord copy() {
                return new HorizontalPageBreakRecord(this);
        }
+
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.HORIZONTAL_PAGE_BREAK;
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java Sun Apr 
12 22:03:52 2020
@@ -20,9 +20,14 @@ package org.apache.poi.hssf.record;
 import static org.apache.poi.hpsf.ClassIDPredefined.FILE_MONIKER;
 import static org.apache.poi.hpsf.ClassIDPredefined.STD_MONIKER;
 import static org.apache.poi.hpsf.ClassIDPredefined.URL_MONIKER;
+import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
+
+import java.util.Map;
+import java.util.function.Supplier;
 
 import org.apache.poi.hpsf.ClassID;
 import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.HexRead;
 import org.apache.poi.util.IOUtils;
@@ -512,16 +517,9 @@ public final class HyperlinkRecord exten
     private static byte[] readTail(byte[] expectedTail, LittleEndianInput in) {
         byte[] result = new byte[TAIL_SIZE];
         in.readFully(result);
-//     if (false) { // Quite a few examples in the unit tests which don't have 
the exact expected tail
-//            for (int i = 0; i < expectedTail.length; i++) {
-//                if (expectedTail[i] != result[i]) {
-//                     logger.log( POILogger.ERROR, "Mismatch in tail byte [" 
+ i + "]"
-//                             + "expected " + (expectedTail[i] & 0xFF) + " 
but got " + (result[i] & 0xFF));
-//                }
-//            }
-//     }
         return result;
     }
+
     private static void writeTail(byte[] tail, LittleEndianOutput out) {
         out.write(tail);
     }
@@ -532,29 +530,6 @@ public final class HyperlinkRecord exten
     }
 
 
-    @Override
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[HYPERLINK RECORD]\n");
-        buffer.append("    .range   = 
").append(_range.formatAsString()).append("\n");
-        buffer.append("    .guid    = ").append(_guid.toString()).append("\n");
-        buffer.append("    .linkOpts= 
").append(HexDump.intToHex(_linkOpts)).append("\n");
-        buffer.append("    .label   = ").append(getLabel()).append("\n");
-        if ((_linkOpts & HLINK_TARGET_FRAME) != 0) {
-            buffer.append("    .targetFrame= 
").append(getTargetFrame()).append("\n");
-        }
-        if((_linkOpts & HLINK_URL) != 0 && _moniker != null) {
-            buffer.append("    .moniker   = 
").append(_moniker.toString()).append("\n");
-        }
-        if ((_linkOpts & HLINK_PLACE) != 0) {
-            buffer.append("    .textMark= 
").append(getTextMark()).append("\n");
-        }
-        buffer.append("    .address   = ").append(getAddress()).append("\n");
-        buffer.append("[/HYPERLINK RECORD]\n");
-        return buffer.toString();
-    }
-
     /**
      * Based on the link options, is this a url?
      *
@@ -636,4 +611,25 @@ public final class HyperlinkRecord exten
     public HyperlinkRecord copy() {
         return new HyperlinkRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.HYPERLINK;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "range", () -> _range,
+            "guid", this::getGuid,
+            "linkOpts", () -> getBitsAsString(this::getLinkOptions,
+                  new 
int[]{HLINK_URL,HLINK_ABS,HLINK_PLACE,HLINK_LABEL,HLINK_TARGET_FRAME,HLINK_UNC_PATH},
+                  new 
String[]{"URL","ABS","PLACE","LABEL","TARGET_FRAME","UNC_PATH"}),
+            "label", this::getLabel,
+            "targetFrame", this::getTargetFrame,
+            "moniker", this::getMoniker,
+            "textMark", this::getTextMark,
+            "address", this::getAddress
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/IndexRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IntList;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
@@ -107,24 +111,6 @@ public final class IndexRecord extends S
     }
 
     @Override
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[INDEX]\n");
-        buffer.append("    .firstrow       = ")
-            .append(Integer.toHexString(getFirstRow())).append("\n");
-        buffer.append("    .lastrowadd1    = ")
-            .append(Integer.toHexString(getLastRowAdd1())).append("\n");
-        for (int k = 0; k < getNumDbcells(); k++) {
-            buffer.append("    .dbcell_").append(k).append(" = ")
-                .append(Integer.toHexString(getDbcellAt(k))).append("\n");
-        }
-        buffer.append("[/INDEX]\n");
-        return buffer.toString();
-    }
-
-    @Override
     public void serialize(LittleEndianOutput out) {
 
         out.writeInt(0);
@@ -156,7 +142,7 @@ public final class IndexRecord extends S
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public IndexRecord clone() {
@@ -165,6 +151,20 @@ public final class IndexRecord extends S
 
     @Override
     public IndexRecord copy() {
-      return new IndexRecord(this);
+        return new IndexRecord(this);
+    }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.INDEX;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "firstRow", this::getFirstRow,
+            "lastRowAdd1", this::getLastRowAdd1,
+            "dbcell_", (field_5_dbcells == null) ? () -> null : 
field_5_dbcells::toArray
+        );
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java Sun 
Apr 12 22:03:52 2020
@@ -17,6 +17,9 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
 
@@ -42,10 +45,6 @@ public final class InterfaceEndRecord ex
         throw new RecordFormatException("Invalid record data size: " + 
in.remaining());
     }
 
-    public String toString() {
-        return "[INTERFACEEND/]\n";
-    }
-
     public void serialize(LittleEndianOutput out) {
         // no instance data
     }
@@ -62,4 +61,14 @@ public final class InterfaceEndRecord ex
     public InterfaceEndRecord copy() {
         return instance;
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.INTERFACE_END;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return null;
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java Sun 
Apr 12 22:03:52 2020
@@ -17,7 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -46,15 +49,6 @@ public final class InterfaceHdrRecord ex
         _codepage = in.readShort();
     }
 
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[INTERFACEHDR]\n");
-        buffer.append("    .codepage = 
").append(HexDump.shortToHex(_codepage)).append("\n");
-        buffer.append("[/INTERFACEHDR]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(_codepage);
     }
@@ -71,4 +65,14 @@ public final class InterfaceHdrRecord ex
     public InterfaceHdrRecord copy() {
         return new InterfaceHdrRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.INTERFACE_HDR;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("codePage", () -> 
_codepage);
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/IterationRecord.java Sun Apr 
12 22:03:52 2020
@@ -17,9 +17,12 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -65,15 +68,6 @@ public final class IterationRecord exten
         return iterationOn.isSet(_flags);
     }
 
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[ITERATION]\n");
-        buffer.append("    .flags      = 
").append(HexDump.shortToHex(_flags)).append("\n");
-        buffer.append("[/ITERATION]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(_flags);
     }
@@ -87,7 +81,7 @@ public final class IterationRecord exten
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public IterationRecord clone() {
@@ -98,4 +92,17 @@ public final class IterationRecord exten
     public IterationRecord copy() {
         return new IterationRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.ITERATION;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "flags", () -> _flags,
+            "iteration", this::getIteration
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/LabelRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -149,21 +153,6 @@ public final class LabelRecord extends R
         return sid;
     }
 
-    @Override
-    public String toString()
-    {
-        StringBuilder sb = new StringBuilder();
-               sb.append("[LABEL]\n");
-               sb.append("    .row       = 
").append(HexDump.shortToHex(getRow())).append("\n");
-               sb.append("    .column    = 
").append(HexDump.shortToHex(getColumn())).append("\n");
-               sb.append("    .xfindex   = 
").append(HexDump.shortToHex(getXFIndex())).append("\n");
-               sb.append("    .string_len= 
").append(HexDump.shortToHex(field_4_string_len)).append("\n");
-               sb.append("    .unicode_flag= 
").append(HexDump.byteToHex(field_5_unicode_flag)).append("\n");
-               sb.append("    .value       = 
").append(getValue()).append("\n");
-               sb.append("[/LABEL]\n");
-        return sb.toString();
-    }
-
     /**
         * NO-OP!
         */
@@ -189,7 +178,7 @@ public final class LabelRecord extends R
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public LabelRecord clone() {
@@ -200,4 +189,21 @@ public final class LabelRecord extends R
     public LabelRecord copy() {
         return new LabelRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.LABEL;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "row", this::getRow,
+            "column", this::getColumn,
+            "xfIndex", this::getXFIndex,
+            "stringLen", this::getStringLength,
+            "unCompressedUnicode", this::isUnCompressedUnicode,
+            "value", this::getValue
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/LabelSSTRecord.java Sun Apr 
12 22:03:52 2020
@@ -17,7 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -67,11 +70,6 @@ public final class LabelSSTRecord extend
     }
 
     @Override
-    protected void appendValueText(StringBuilder sb) {
-               sb.append("  .sstIndex = ");
-       sb.append(HexDump.shortToHex(getSSTIndex()));
-    }
-    @Override
     protected void serializeValue(LittleEndianOutput out) {
         out.writeInt(getSSTIndex());
     }
@@ -87,7 +85,7 @@ public final class LabelSSTRecord extend
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public LabelSSTRecord clone() {
@@ -98,4 +96,17 @@ public final class LabelSSTRecord extend
     public LabelSSTRecord copy() {
         return new LabelSSTRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.LABEL_SST;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "base", super::getGenericProperties,
+            "sstIndex", this::getSSTIndex
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/LbsDataSubRecord.java Sun Apr 
12 22:03:52 2020
@@ -16,9 +16,16 @@
 ==================================================================== */
 package org.apache.poi.hssf.record;
 
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.common.Duplicatable;
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.ss.formula.ptg.Ptg;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordJsonWriter;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
@@ -287,27 +294,6 @@ public class LbsDataSubRecord extends Su
         return new LbsDataSubRecord(this);
     }
 
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(256);
-
-        sb.append("[ftLbsData]\n");
-        sb.append("    .unknownShort1 
=").append(HexDump.shortToHex(_cbFContinued)).append("\n");
-        sb.append("    .formula        = ").append('\n');
-        if(_linkPtg != null) {
-            sb.append(_linkPtg).append(_linkPtg.getRVAType()).append('\n');
-        }
-        sb.append("    .nEntryCount   
=").append(HexDump.shortToHex(_cLines)).append("\n");
-        sb.append("    .selEntryIx    
=").append(HexDump.shortToHex(_iSel)).append("\n");
-        sb.append("    .style         
=").append(HexDump.shortToHex(_flags)).append("\n");
-        sb.append("    
.unknownShort10=").append(HexDump.shortToHex(_idEdit)).append("\n");
-        if(_dropData != null) {
-            sb.append('\n').append(_dropData);
-        }
-        sb.append("[/ftLbsData]\n");
-        return sb.toString();
-    }
-
     /**
      *
      * @return the formula that specifies the range of cell values that are 
the items in this list.
@@ -323,10 +309,32 @@ public class LbsDataSubRecord extends Su
         return _cLines;
     }
 
+    @Override
+    public SubRecordTypes getGenericRecordType() {
+        return SubRecordTypes.LBS_DATA;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+        m.put("unknownShort1", () -> _cbFContinued);
+        m.put("unknownPreFormulaInt", () -> _unknownPreFormulaInt);
+        m.put("formula", this::getFormula);
+        m.put("unknownPostFormulaByte", () -> _unknownPostFormulaByte);
+        m.put("numberOfItems", this::getNumberOfItems);
+        m.put("selEntryIx", () -> _iSel);
+        m.put("style", () -> _flags);
+        m.put("unknownShort10", () -> _idEdit);
+        m.put("dropData", () -> _dropData);
+        m.put("rgLines", () -> _rgLines);
+        m.put("bsels", () -> _bsels);
+        return Collections.unmodifiableMap(m);
+    }
+
     /**
      * This structure specifies properties of the dropdown list control
      */
-    public static class LbsDropData implements Duplicatable {
+    public static class LbsDropData implements Duplicatable, GenericRecord {
         /**
          * Combo dropdown control
          */
@@ -435,23 +443,23 @@ public class LbsDataSubRecord extends Su
 
         @Override
         public String toString(){
-            StringBuilder sb = new StringBuilder();
-            sb.append("[LbsDropData]\n");
-            sb.append("  ._wStyle:  ").append(_wStyle).append('\n');
-            sb.append("  ._cLine:  ").append(_cLine).append('\n');
-            sb.append("  ._dxMin:  ").append(_dxMin).append('\n');
-            sb.append("  ._str:  ").append(_str).append('\n');
-            if(_unused != null) {
-                sb.append("  ._unused:  ").append(_unused).append('\n');
-            }
-            sb.append("[/LbsDropData]\n");
-
-            return sb.toString();
+            return GenericRecordJsonWriter.marshal(this);
         }
 
         @Override
         public LbsDropData copy() {
             return new LbsDropData(this);
         }
+
+        @Override
+        public Map<String, Supplier<?>> getGenericProperties() {
+            return GenericRecordUtil.getGenericProperties(
+                "wStyle", () -> _wStyle,
+                "cLine", () -> _cLine,
+                "dxMin", () -> _dxMin,
+                "str", () -> _str,
+                "unused", () -> _unused
+            );
+        }
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/LeftMarginRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/LeftMarginRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/LeftMarginRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/LeftMarginRecord.java Sun Apr 
12 22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -38,15 +42,6 @@ public final class LeftMarginRecord exte
         field_1_margin = in.readDouble();
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append( "[LeftMargin]\n" );
-        buffer.append( "    .margin               = " ).append( " (" ).append( 
getMargin() ).append( " )\n" );
-        buffer.append( "[/LeftMargin]\n" );
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeDouble(field_1_margin);
     }
@@ -75,7 +70,7 @@ public final class LeftMarginRecord exte
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public LeftMarginRecord clone() {
@@ -86,4 +81,14 @@ public final class LeftMarginRecord exte
     public LeftMarginRecord copy() {
         return new LeftMarginRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.LEFT_MARGIN;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("margin", 
this::getMargin);
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/MMSRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/MMSRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/MMSRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/MMSRecord.java Sun Apr 12 
22:03:52 2020
@@ -19,6 +19,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
@@ -89,19 +93,6 @@ public final class MMSRecord extends Sta
         return field_2_delMenuCount;
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[MMS]\n");
-        buffer.append("    .addMenu        = ")
-            .append(Integer.toHexString(getAddMenuCount())).append("\n");
-        buffer.append("    .delMenu        = ")
-            .append(Integer.toHexString(getDelMenuCount())).append("\n");
-        buffer.append("[/MMS]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeByte(getAddMenuCount());
         out.writeByte(getDelMenuCount());
@@ -120,4 +111,17 @@ public final class MMSRecord extends Sta
     public MMSRecord copy() {
         return new MMSRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.MMS;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "addMenuCount", this::getAddMenuCount,
+            "delMenuCount", this::getDelMenuCount
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/MergeCellsRecord.java Sun Apr 
12 22:03:52 2020
@@ -17,10 +17,14 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Supplier;
 import java.util.stream.Stream;
 
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -100,25 +104,7 @@ public final class MergeCellsRecord exte
     }
 
     @Override
-    public String toString() {
-        StringBuilder retval = new StringBuilder();
-
-        retval.append("[MERGEDCELLS]").append("\n");
-        retval.append("     .numregions =").append(getNumAreas()).append("\n");
-        for (int k = 0; k < _numberOfRegions; k++) {
-            CellRangeAddress r = _regions[_startIndex + k];
-
-            retval.append("     .rowfrom 
=").append(r.getFirstRow()).append("\n");
-            retval.append("     .rowto   
=").append(r.getLastRow()).append("\n");
-            retval.append("     .colfrom 
=").append(r.getFirstColumn()).append("\n");
-            retval.append("     .colto   
=").append(r.getLastColumn()).append("\n");
-        }
-        retval.append("[MERGEDCELLS]").append("\n");
-        return retval.toString();
-    }
-
-    @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public MergeCellsRecord clone() {
@@ -129,4 +115,17 @@ public final class MergeCellsRecord exte
     public MergeCellsRecord copy() {
         return new MergeCellsRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.MERGE_CELLS;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "numRegions", this::getNumAreas,
+            "regions", () -> Arrays.copyOfRange(_regions, _startIndex, 
_startIndex+_numberOfRegions)
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/MulBlankRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/MulBlankRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/MulBlankRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/MulBlankRecord.java Sun Apr 
12 22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -97,21 +101,6 @@ public final class MulBlankRecord extend
                return retval;
        }
 
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[MULBLANK]\n");
-               buffer.append("row  = 
").append(Integer.toHexString(getRow())).append("\n");
-               buffer.append("firstcol  = 
").append(Integer.toHexString(getFirstColumn())).append("\n");
-               buffer.append(" lastcol  = 
").append(Integer.toHexString(_lastCol)).append("\n");
-               for (int k = 0; k < getNumColumns(); k++) {
-                       buffer.append("xf").append(k).append("          = 
").append(
-                                       
Integer.toHexString(getXFAt(k))).append("\n");
-               }
-               buffer.append("[/MULBLANK]\n");
-               return buffer.toString();
-       }
-
        public short getSid() {
                return sid;
        }
@@ -119,7 +108,6 @@ public final class MulBlankRecord extend
        public void serialize(LittleEndianOutput out) {
                out.writeShort(_row);
                out.writeShort(_firstCol);
-               int nItems = _xfs.length;
                for (short xf : _xfs) {
                        out.writeShort(xf);
                }
@@ -132,7 +120,7 @@ public final class MulBlankRecord extend
        }
 
        @Override
-       @SuppressWarnings("squid:S2975")
+       @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
        @Deprecated
        @Removal(version = "5.0.0")
        public MulBlankRecord clone() {
@@ -144,4 +132,19 @@ public final class MulBlankRecord extend
                // immutable - so OK to return this
                return this;
        }
+
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.MUL_BLANK;
+       }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "row", this::getRow,
+                       "firstColumn", this::getFirstColumn,
+                       "lastColumn", this::getLastColumn,
+                       "xf", () -> _xfs
+               );
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/MulRKRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/MulRKRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/MulRKRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/MulRKRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,8 +17,12 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.common.usermodel.GenericRecord;
 import org.apache.poi.hssf.util.RKUtil;
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.RecordFormatException;
 
@@ -96,24 +100,6 @@ public final class MulRKRecord extends S
                field_4_last_col = in.readShort();
        }
 
-
-       @Override
-    public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[MULRK]\n");
-               buffer.append(" .row     = 
").append(HexDump.shortToHex(getRow())).append("\n");
-               buffer.append(" .firstcol= 
").append(HexDump.shortToHex(getFirstColumn())).append("\n");
-               buffer.append(" .lastcol = 
").append(HexDump.shortToHex(getLastColumn())).append("\n");
-
-               for (int k = 0; k < getNumColumns(); k++) {
-                       buffer.append(" xf[").append(k).append("] = 
").append(HexDump.shortToHex(getXFAt(k))).append("\n");
-                       buffer.append(" rk[").append(k).append("] = 
").append(getRKNumberAt(k)).append("\n");
-               }
-               buffer.append("[/MULRK]\n");
-               return buffer.toString();
-       }
-
        @Override
     public short getSid()
        {
@@ -129,7 +115,7 @@ public final class MulRKRecord extends S
                throw new RecordFormatException( "Sorry, you can't serialize 
MulRK in this release");
        }
 
-       private static final class RkRec {
+       private static final class RkRec implements GenericRecord {
                public static final int ENCODED_SIZE = 6;
                public final short xf;
                public final int   rk;
@@ -147,6 +133,14 @@ public final class MulRKRecord extends S
                        }
                        return retval;
                }
+
+               @Override
+               public Map<String, Supplier<?>> getGenericProperties() {
+                       return GenericRecordUtil.getGenericProperties(
+                               "xf", () -> xf,
+                               "rk", () -> rk
+                       );
+               }
        }
 
        @Override
@@ -154,4 +148,19 @@ public final class MulRKRecord extends S
                // immutable - so OK to return this
                return this;
        }
+
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.MUL_RK;
+       }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "row", this::getRow,
+                       "firstColumn", this::getFirstColumn,
+                       "lastColumn", this::getLastColumn,
+                       "rk", () -> field_3_rks
+               );
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/NameCommentRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/NameCommentRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/NameCommentRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/NameCommentRecord.java Sun 
Apr 12 22:03:52 2020
@@ -17,7 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.StringUtil;
 
@@ -115,23 +118,6 @@ public final class NameCommentRecord ext
         return sid;
     }
 
-    @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder();
-
-        sb.append("[NAMECMT]\n");
-        sb.append("    .record type            = 
").append(HexDump.shortToHex(field_1_record_type)).append("\n");
-        sb.append("    .frt cell ref flag      = 
").append(HexDump.byteToHex(field_2_frt_cell_ref_flag)).append("\n");
-        sb.append("    .reserved               = 
").append(field_3_reserved).append("\n");
-        sb.append("    .name length            = 
").append(field_6_name_text.length()).append("\n");
-        sb.append("    .comment length         = 
").append(field_7_comment_text.length()).append("\n");
-        sb.append("    .name                   = 
").append(field_6_name_text).append("\n");
-        sb.append("    .comment                = 
").append(field_7_comment_text).append("\n");
-        sb.append("[/NAMECMT]\n");
-
-        return sb.toString();
-    }
-
     /**
      * @return the name of the NameRecord to which this comment applies.
      */
@@ -168,4 +154,20 @@ public final class NameCommentRecord ext
     public NameCommentRecord copy() {
         return new NameCommentRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.NAME_COMMENT;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "recordType", this::getRecordType,
+            "frtCellRefFlag", () -> field_2_frt_cell_ref_flag,
+            "reserved", () -> field_3_reserved,
+            "name", this::getNameText,
+            "comment", this::getCommentText
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/NameRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,13 +17,17 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
 import org.apache.poi.hssf.record.cont.ContinuableRecord;
 import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
 import org.apache.poi.ss.formula.Formula;
 import org.apache.poi.ss.formula.ptg.Area3DPtg;
 import org.apache.poi.ss.formula.ptg.Ptg;
 import org.apache.poi.ss.formula.ptg.Ref3DPtg;
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianByteArrayInputStream;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.StringUtil;
@@ -31,6 +35,7 @@ import org.apache.poi.util.StringUtil;
 /**
  * Defines a named range within a workbook.
  */
+@SuppressWarnings("unused")
 public final class NameRecord extends ContinuableRecord {
     public static final short sid = 0x0018;
        /**Included for completeness sake, not implemented */
@@ -238,6 +243,7 @@ public final class NameRecord extends Co
        public boolean isHiddenName() {
                return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0;
        }
+
        public void setHidden(boolean b) {
                if (b) {
                        field_1_option_flag |= Option.OPT_HIDDEN_NAME;
@@ -416,7 +422,7 @@ public final class NameRecord extends Co
                return nChars;
        }
 
-       protected int getDataSize() {
+       int getDataSize() {
                return 13 // 3 shorts + 7 bytes
                        + getNameRawSize()
                        + field_14_custom_menu_text.length()
@@ -552,37 +558,6 @@ public final class NameRecord extends Co
          3B 00 00 07 00 07 00 00 00 FF 00 ]
         */
 
-       @Override
-    public String toString() {
-               StringBuilder sb = new StringBuilder();
-
-               sb.append("[NAME]\n");
-               sb.append("    .option flags           = 
").append(HexDump.shortToHex(field_1_option_flag)).append("\n");
-               sb.append("    .keyboard shortcut      = 
").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n");
-               sb.append("    .length of the name     = 
").append(getNameTextLength()).append("\n");
-               sb.append("    .extSheetIx(1-based, 0=Global)= ").append( 
field_5_externSheetIndex_plus1 ).append("\n");
-               sb.append("    .sheetTabIx             = 
").append(field_6_sheetNumber ).append("\n");
-               sb.append("    .Menu text length       = 
").append(field_14_custom_menu_text.length()).append("\n");
-               sb.append("    .Description text length= 
").append(field_15_description_text.length()).append("\n");
-               sb.append("    .Help topic text length = 
").append(field_16_help_topic_text.length()).append("\n");
-               sb.append("    .Status bar text length = 
").append(field_17_status_bar_text.length()).append("\n");
-               sb.append("    .NameIsMultibyte        = 
").append(field_11_nameIsMultibyte).append("\n");
-               sb.append("    .Name (Unicode text)    = ").append( 
getNameText() ).append("\n");
-               Ptg[] ptgs = field_13_name_definition.getTokens();
-               sb.append("    .Formula 
(nTokens=").append(ptgs.length).append("):") .append("\n");
-               for (Ptg ptg : ptgs) {
-                       sb.append("       
").append(ptg).append(ptg.getRVAType()).append("\n");
-               }
-
-               sb.append("    .Menu text       = 
").append(field_14_custom_menu_text).append("\n");
-               sb.append("    .Description text= 
").append(field_15_description_text).append("\n");
-               sb.append("    .Help topic text = 
").append(field_16_help_topic_text).append("\n");
-               sb.append("    .Status bar text = 
").append(field_17_status_bar_text).append("\n");
-               sb.append("[/NAME]\n");
-
-               return sb.toString();
-       }
-
        /**Creates a human readable name for built in types
         * @return Unknown if the built-in name cannot be translated
         */
@@ -613,4 +588,29 @@ public final class NameRecord extends Co
        public NameRecord copy() {
                return new NameRecord(this);
        }
+
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.NAME;
+       }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               final Map<String,Supplier<?>> m = new LinkedHashMap<>();
+               m.put("dataSize", this::getDataSize);
+               m.put("optionFlag", this::getOptionFlag);
+               m.put("keyboardShortcut", this::getKeyboardShortcut);
+               m.put("externSheetIndex", () -> field_5_externSheetIndex_plus1);
+               m.put("sheetNumber", this::getSheetNumber);
+               m.put("nameIsMultibyte", () -> field_11_nameIsMultibyte);
+               m.put("builtInName", this::getBuiltInName);
+               m.put("nameLength", this::getNameTextLength);
+               m.put("nameText", this::getNameText);
+               m.put("formula", this::getNameDefinition);
+               m.put("customMenuText", this::getCustomMenuText);
+               m.put("descriptionText", this::getDescriptionText);
+               m.put("helpTopicText", this::getHelpTopicText);
+               m.put("statusBarText", this::getStatusBarText);
+               return Collections.unmodifiableMap(m);
+       }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/NoteRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/NoteRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/NoteRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/NoteRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,6 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 import org.apache.poi.util.StringUtil;
@@ -102,10 +106,10 @@ public final class NoteRecord extends St
                        field_6_author = StringUtil.readCompressedUnicode(in, 
length);
                }
                if (in.available() == 1) {
-                       field_7_padding = Byte.valueOf(in.readByte());
+                       field_7_padding = in.readByte();
                } else if (in.available() == 2 && length == 0) {
                    // If there's no author, may be double padded
-            field_7_padding = Byte.valueOf(in.readByte());
+            field_7_padding = in.readByte();
             in.readByte();
                }
        }
@@ -134,23 +138,6 @@ public final class NoteRecord extends St
        }
 
        /**
-        * Convert this record to string.
-        * Used by BiffViewer and other utilities.
-        */
-       public String toString() {
-               StringBuilder buffer = new StringBuilder();
-
-               buffer.append("[NOTE]\n");
-               buffer.append("    .row    = 
").append(field_1_row).append("\n");
-               buffer.append("    .col    = 
").append(field_2_col).append("\n");
-               buffer.append("    .flags  = 
").append(field_3_flags).append("\n");
-               buffer.append("    .shapeid= 
").append(field_4_shapeid).append("\n");
-               buffer.append("    .author = 
").append(field_6_author).append("\n");
-               buffer.append("[/NOTE]\n");
-               return buffer.toString();
-       }
-
-       /**
         * Return the row that contains the comment
         *
         * @return the row that contains the comment
@@ -213,7 +200,7 @@ public final class NoteRecord extends St
         *
         * @return true, if author element uses multi byte
         */
-       protected boolean authorIsMultibyte() {
+       boolean authorIsMultibyte() {
           return field_5_hasMultibyte;
        }
 
@@ -255,7 +242,7 @@ public final class NoteRecord extends St
        }
 
        @Override
-       @SuppressWarnings("squid:S2975")
+       @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
        @Deprecated
        @Removal(version = "5.0.0")
        public NoteRecord clone() {
@@ -266,4 +253,20 @@ public final class NoteRecord extends St
        public NoteRecord copy() {
                return new NoteRecord(this);
        }
+
+       @Override
+       public HSSFRecordTypes getGenericRecordType() {
+               return HSSFRecordTypes.NOTE;
+       }
+
+       @Override
+       public Map<String, Supplier<?>> getGenericProperties() {
+               return GenericRecordUtil.getGenericProperties(
+                       "row", this::getRow,
+                       "column", this::getColumn,
+                       "flags", this::getFlags,
+                       "shapeId", this::getShapeId,
+                       "author", this::getAuthor
+               );
+       }
 }

Modified: 
poi/trunk/src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/NoteStructureSubRecord.java 
Sun Apr 12 22:03:52 2020
@@ -17,7 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.util.HexDump;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndianInput;
 import org.apache.poi.util.LittleEndianOutput;
@@ -58,6 +61,10 @@ public final class NoteStructureSubRecor
      * @param size the provided size - must be 22
      */
     public NoteStructureSubRecord(LittleEndianInput in, int size) {
+        this(in,size,-1);
+    }
+
+    public NoteStructureSubRecord(LittleEndianInput in, int size, int cmoOt) {
         if (size != ENCODED_SIZE) {
             throw new RecordFormatException("Unexpected size (" + size + ")");
         }
@@ -68,22 +75,6 @@ public final class NoteStructureSubRecor
     }
 
     /**
-     * Convert this record to string.
-     * Used by BiffViewer and other utilities.
-     */
-    @Override
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[ftNts ]").append("\n");
-        buffer.append("  size     = ").append(getDataSize()).append("\n");
-        buffer.append("  reserved = 
").append(HexDump.toHex(reserved)).append("\n");
-        buffer.append("[/ftNts ]").append("\n");
-        return buffer.toString();
-    }
-
-    /**
      * Serialize the record data into the supplied array of bytes
      *
      * @param out the stream to serialize into
@@ -121,6 +112,17 @@ public final class NoteStructureSubRecor
         return new NoteStructureSubRecord(this);
     }
 
+    @Override
+    public SubRecordTypes getGenericRecordType() {
+        return SubRecordTypes.NOTE_STRUCTURE;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "reserved", () -> reserved
+        );
+    }
 }
 
 

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/NumberRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/NumberRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/NumberRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/NumberRecord.java Sun Apr 12 
22:03:52 2020
@@ -17,7 +17,10 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.ss.util.NumberToTextConverter;
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -69,11 +72,6 @@ public final class NumberRecord extends
     }
 
     @Override
-    protected void appendValueText(StringBuilder sb) {
-        sb.append("  .value= 
").append(NumberToTextConverter.toText(field_4_value));
-    }
-
-    @Override
     protected void serializeValue(LittleEndianOutput out) {
         out.writeDouble(getValue());
     }
@@ -89,7 +87,7 @@ public final class NumberRecord extends
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public NumberRecord clone() {
@@ -100,4 +98,17 @@ public final class NumberRecord extends
     public NumberRecord copy() {
         return new NumberRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.NUMBER;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+           "base", super::getGenericProperties,
+           "value", this::getValue
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java Sun Apr 12 
22:03:52 2020
@@ -20,7 +20,10 @@ package org.apache.poi.hssf.record;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
 
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.LittleEndianByteArrayInputStream;
@@ -140,18 +143,6 @@ public final class ObjRecord extends Rec
     }
 
     @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append("[OBJ]\n");
-        for (final SubRecord record : subrecords) {
-            sb.append("SUBRECORD: ").append(record);
-        }
-        sb.append("[/OBJ]\n");
-        return sb.toString();
-    }
-
-    @Override
     public int getRecordSize() {
         if (_uninterpretedData != null) {
             return _uninterpretedData.length + 4;
@@ -225,7 +216,7 @@ public final class ObjRecord extends Rec
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public ObjRecord clone() {
@@ -236,4 +227,22 @@ public final class ObjRecord extends Rec
     public ObjRecord copy() {
         return new ObjRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.OBJ;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "uninterpretedData", () -> _uninterpretedData,
+            "paddedToQuadByteMultiple", () -> _isPaddedToQuadByteMultiple
+        );
+    }
+
+    @Override
+    public List<SubRecord> getGenericChildren() {
+        return getSubRecords();
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ObjectProtectRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ObjectProtectRecord.java?rev=1876433&r1=1876432&r2=1876433&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ObjectProtectRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ObjectProtectRecord.java Sun 
Apr 12 22:03:52 2020
@@ -19,6 +19,10 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Map;
+import java.util.function.Supplier;
+
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndianOutput;
 import org.apache.poi.util.Removal;
 
@@ -64,17 +68,6 @@ public final class ObjectProtectRecord e
         return (field_1_protect == 1);
     }
 
-    public String toString()
-    {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append("[SCENARIOPROTECT]\n");
-        buffer.append("    .protect         = ").append(getProtect())
-            .append("\n");
-        buffer.append("[/SCENARIOPROTECT]\n");
-        return buffer.toString();
-    }
-
     public void serialize(LittleEndianOutput out) {
         out.writeShort(field_1_protect);
     }
@@ -89,7 +82,7 @@ public final class ObjectProtectRecord e
     }
 
     @Override
-    @SuppressWarnings("squid:S2975")
+    @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
     @Deprecated
     @Removal(version = "5.0.0")
     public ObjectProtectRecord clone() {
@@ -100,4 +93,14 @@ public final class ObjectProtectRecord e
     public ObjectProtectRecord copy() {
         return new ObjectProtectRecord(this);
     }
+
+    @Override
+    public HSSFRecordTypes getGenericRecordType() {
+        return HSSFRecordTypes.OBJECT_PROTECT;
+    }
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties("protect", 
this::getProtect);
+    }
 }



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

Reply via email to