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

svn commit: r1868352 [1/6] - in /poi/trunk/src: java/org/apache/poi/ddf/ java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/usermodel/ java/org/apache/poi/sl/usermodel/ scratchpad/src/org/apache/poi/hslf/model/ scratchpad/src/org/apache/poi/hslf/...

Author: kiwiwings
Date: Sat Oct 12 16:32:53 2019
New Revision: 1868352

URL: http://svn.apache.org/viewvc?rev=1868352&view=rev
Log:
#63745 - Add traversing and debugging interface
Replace EscherProperty.getAttributeMap by GenericRecord interface

Added:
    poi/trunk/src/java/org/apache/poi/ddf/EscherPropertyTypes.java   (with props)
    poi/trunk/src/java/org/apache/poi/ddf/EscherPropertyTypesHolder.java   (with props)
Modified:
    poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherDump.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherProperties.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherProperty.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherPropertyFactory.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherShapePathProperty.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherSpgrRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherSplitMenuColorsRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherTextboxRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/UnknownEscherRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCombobox.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFComment.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFPolygon.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShape.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeFactory.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFShapeGroup.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSimpleShape.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFTextbox.java
    poi/trunk/src/java/org/apache/poi/sl/usermodel/PictureData.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ActiveXShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/HSLFMetroShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Polygon.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFAutoShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFill.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFLine.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapePlaceholderDetails.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTable.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTableCell.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextBox.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfColorRef.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/OfficeDrawingsImpl.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Picture.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBackground.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherBSERecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherBlipRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherBoolProperty.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherChildAnchorRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherClientAnchorRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherClientDataRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDgRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDggRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherDump.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherOptRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherProperty.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherSpRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherSpgrRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherSplitMenuColorsRecord.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestUnknownEscherRecord.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestDrawingShapes.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestPolygon.java

Modified: poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java Sat Oct 12 16:32:53 2019
@@ -24,6 +24,7 @@ import java.util.function.Supplier;
 
 import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.Removal;
 
 /**
  * Common abstract class for {@link EscherOptRecord} and
@@ -96,18 +97,13 @@ public abstract class AbstractEscherOptR
         return 8 + getPropertiesSize();
     }
 
-    public <T extends EscherProperty> T lookup( int propId )
-    {
-        for ( EscherProperty prop : properties )
-        {
-            if ( prop.getPropertyNumber() == propId )
-            {
-                @SuppressWarnings( "unchecked" )
-                final T result = (T) prop;
-                return result;
-            }
-        }
-        return null;
+    public <T extends EscherProperty> T lookup( EscherPropertyTypes propType ) {
+        return lookup(propType.propNumber);
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public <T extends EscherProperty> T lookup( int propId ) {
+        return (T)properties.stream().filter(p -> p.getPropertyNumber() == propId).findFirst().orElse(null);
     }
 
     @Override
@@ -140,8 +136,7 @@ public abstract class AbstractEscherOptR
     }
 
     /**
-     * Set an escher property. If a property with given propId already
-     exists it is replaced.
+     * Set an escher property. If a property with given propId already exists it is replaced.
      *
      * @param value the property to set.
      */
@@ -151,32 +146,22 @@ public abstract class AbstractEscherOptR
         sortProperties();
     }
 
+    @Deprecated
+    @Removal(version = "5.0.0")
     public void removeEscherProperty(int num){
         properties.removeIf(prop -> prop.getPropertyNumber() == num);
     }
 
-    @Override
-    protected Object[][] getAttributeMap() {
-        List<Object> attrList = new ArrayList<>(properties.size() * 2 + 2);
-        attrList.add("properties");
-        attrList.add(properties.size());
-        for ( EscherProperty property : properties ) {
-            attrList.add(property.getName());
-            attrList.add(property);
-        }
-        
-        return new Object[][]{
-            { "isContainer", isContainerRecord() },
-            { "numchildren", getChildRecords().size() },
-            attrList.toArray()
-        };
+    public void removeEscherProperty(EscherPropertyTypes type){
+        properties.removeIf(prop -> prop.getPropertyNumber() == type.propNumber);
     }
 
     @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
             "base", super::getGenericProperties,
-            "isContainer", this::isContainerRecord
+            "isContainer", this::isContainerRecord,
+            "properties", this::getEscherProperties
         );
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java Sat Oct 12 16:32:53 2019
@@ -18,11 +18,17 @@
 package org.apache.poi.ddf;
 
 import java.util.Iterator;
+import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 
-import org.apache.poi.util.HexDump;
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.Internal;
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.Removal;
 
 /**
  * Escher array properties are the most weird construction ever invented
@@ -30,17 +36,15 @@ import org.apache.poi.util.LittleEndian;
  */
 public final class EscherArrayProperty extends EscherComplexProperty implements Iterable<byte[]> {
 
-    //arbitrarily selected; may need to increase
+    // arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 100_000;
 
     /**
-     * The size of the header that goes at the
-     *  start of the array, before the data
+     * The size of the header that goes at the start of the array, before the data
      */
     private static final int FIXED_SIZE = 3 * 2;
     /**
-     * Normally, the size recorded in the simple data (for the complex
-     *  data) includes the size of the header.
+     * Normally, the size recorded in the simple data (for the complex data) includes the size of the header.
      * There are a few cases when it doesn't though...
      */
     private boolean sizeIncludesHeaderSize = true;
@@ -48,50 +52,105 @@ public final class EscherArrayProperty e
     /**
      * When reading a property from data stream remember if the complex part is empty and set this flag.
      */
-    private boolean emptyComplexPart;
+    private final boolean emptyComplexPart;
 
+    /**
+     * Create an instance of an escher array property.
+     * This constructor defaults to a 6 bytes header if the complexData is null or byte[0].
+     *
+     * @param id          The id consists of the property number, a flag indicating whether this is a blip id and a flag
+     *                    indicating that this is a complex property.
+     * @param complexData The value of this property.
+     *
+     * @deprecated use {@link #EscherArrayProperty(EscherPropertyTypes, boolean, int)} and {@link #setComplexData(byte[])}
+     */
+    @Deprecated
+    @Removal(version = "5.0.0")
+    @Internal
     public EscherArrayProperty(short id, byte[] complexData) {
-        super(id, checkComplexData(complexData));
-        emptyComplexPart = (complexData == null || complexData.length == 0);
+        this(id, safeSize(complexData == null ? 0 : complexData.length));
+        setComplexData(complexData);
     }
 
-    public EscherArrayProperty(short propertyNumber, boolean isBlipId, byte[] complexData) {
-        super(propertyNumber, isBlipId, checkComplexData(complexData));
+    /**
+     * Create an instance of an escher array property.
+     * This constructor can be used to create emptyComplexParts with a complexSize = 0.
+     * Preferably use {@link #EscherArrayProperty(EscherPropertyTypes, boolean, int)} with {@link #setComplexData(byte[])}.
+     *
+     * @param id          The id consists of the property number, a flag indicating whether this is a blip id and a flag
+     *                    indicating that this is a complex property.
+     * @param complexSize the data size
+     */
+    @Internal
+    public EscherArrayProperty(short id, int complexSize) {
+        // this is called by EscherPropertyFactory which happens to call it with empty parts
+        // if a part is initial empty, don't allow it to contain something again
+        super(id, complexSize);
+        emptyComplexPart = (complexSize == 0);
     }
 
-    private static byte[] checkComplexData(byte[] complexData) {
-        if (complexData == null || complexData.length == 0) {
-            return new byte[6];
-        }
+    /**
+     * Create an instance of an escher array property.
+     * This constructor defaults to a 6 bytes header if the complexData is null or byte[0].
+     *
+     * @param propertyNumber the property number part of the property id
+     * @param isBlipId {@code true}, if it references a blip
+     * @param complexData the data
+     *                    
+     * @deprecated use {@link #EscherArrayProperty(EscherPropertyTypes, boolean, int)} and {@link #setComplexData(byte[])}
+     */
+    @Deprecated
+    @Removal(version = "5.0.0")
+    public EscherArrayProperty(short propertyNumber, boolean isBlipId, byte[] complexData) {
+        // this is called by user code, if the complexData is empty/null, allocate a space for a valid header
+        // be aware, that there are complex data areas with less than 6 bytes
+        this((short)(propertyNumber | (isBlipId ? IS_BLIP : 0)), safeSize(complexData == null ? 0 : complexData.length));
+        setComplexData(complexData);
+    }
 
-        return complexData;
+    /**
+     * Create an instance of an escher array property.
+     * This constructor defaults to a 6 bytes header if the complexSize is 0.
+     *
+     * @param type the property type of the property id
+     * @param isBlipId {@code true}, if it references a blip
+     * @param complexSize the data size
+     */
+    public EscherArrayProperty(EscherPropertyTypes type, boolean isBlipId, int complexSize) {
+        this((short)(type.propNumber | (isBlipId ? IS_BLIP : 0)), safeSize(complexSize));
     }
 
+    private static int safeSize(int complexSize) {
+        // when called by user code, fix the size to be valid for the header
+        return complexSize == 0 ? 6 : complexSize;
+    }
+    
     public int getNumberOfElementsInArray() {
         return (emptyComplexPart) ? 0 : LittleEndian.getUShort(getComplexData(), 0);
     }
 
     public void setNumberOfElementsInArray(int numberOfElements) {
-        int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
-        if (expectedArraySize != getComplexData().length) {
-            byte[] newArray = IOUtils.safelyAllocate(expectedArraySize, MAX_RECORD_LENGTH);
-            System.arraycopy(getComplexData(), 0, newArray, 0, getComplexData().length);
-            setComplexData(newArray);
+        if (emptyComplexPart) {
+            return;
         }
+        rewriteArray(numberOfElements, false);
         LittleEndian.putShort(getComplexData(), 0, (short) numberOfElements);
     }
 
+    private void rewriteArray(int numberOfElements, boolean copyToNewLen) {
+        int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
+        resizeComplexData(expectedArraySize, copyToNewLen ? expectedArraySize : getComplexData().length);
+    }
+
     public int getNumberOfElementsInMemory() {
         return (emptyComplexPart) ? 0 : LittleEndian.getUShort(getComplexData(), 2);
     }
 
     public void setNumberOfElementsInMemory(int numberOfElements) {
-        int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
-        if (expectedArraySize != getComplexData().length) {
-            byte[] newArray = IOUtils.safelyAllocate(expectedArraySize, MAX_RECORD_LENGTH);
-            System.arraycopy(getComplexData(), 0, newArray, 0, expectedArraySize);
-            setComplexData(newArray);
+        if (emptyComplexPart) {
+            return;
         }
+        rewriteArray(numberOfElements, true);
         LittleEndian.putShort(getComplexData(), 2, (short) numberOfElements);
     }
 
@@ -100,15 +159,14 @@ public final class EscherArrayProperty e
     }
 
     public void setSizeOfElements(int sizeOfElements) {
+        if (emptyComplexPart) {
+            return;
+        }
         LittleEndian.putShort( getComplexData(), 4, (short) sizeOfElements );
 
         int expectedArraySize = getNumberOfElementsInArray() * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
-        if (expectedArraySize != getComplexData().length) {
-            // Keep just the first 6 bytes.  The rest is no good to us anyway.
-            byte[] newArray = IOUtils.safelyAllocate(expectedArraySize, MAX_RECORD_LENGTH);
-            System.arraycopy( getComplexData(), 0, newArray, 0, 6 );
-            setComplexData(newArray);
-        }
+        // Keep just the first 6 bytes.  The rest is no good to us anyway.
+        resizeComplexData(expectedArraySize, 6);
     }
 
     public byte[] getElement(int index) {
@@ -119,43 +177,13 @@ public final class EscherArrayProperty e
     }
 
     public void setElement(int index, byte[] element) {
+        if (emptyComplexPart) {
+            return;
+        }
         int actualSize = getActualSizeOfElements(getSizeOfElements());
         System.arraycopy( element, 0, getComplexData(), FIXED_SIZE + index * actualSize, actualSize);
     }
 
-    @Override
-    public String toString() {
-        StringBuilder results = new StringBuilder();
-        results.append("propNum: ").append(getPropertyNumber());
-        results.append(", propName: ").append(EscherProperties.getPropertyName( getPropertyNumber() ));
-        results.append(", complex: ").append(isComplex());
-        results.append(", blipId: ").append(isBlipId());
-        results.append(", data: \n");
-        results.append("    {EscherArrayProperty:" + '\n');
-        results.append("     Num Elements: ").append(getNumberOfElementsInArray()).append('\n');
-        results.append("     Num Elements In Memory: ").append(getNumberOfElementsInMemory()).append('\n');
-        results.append("     Size of elements: ").append(getSizeOfElements()).append('\n');
-        for (int i = 0; i < getNumberOfElementsInArray(); i++) {
-            results.append("     Element ").append(i).append(": ").append(HexDump.toHex(getElement(i))).append('\n');
-        }
-        results.append("}" + '\n');
-
-        return results.toString();
-    }
-
-    @Override
-    public String toXml(String tab){
-        StringBuilder builder = new StringBuilder();
-        builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId()))
-                .append("\" name=\"").append(getName()).append("\" blipId=\"")
-                .append(isBlipId()).append("\">\n");
-        for (int i = 0; i < getNumberOfElementsInArray(); i++) {
-            builder.append("\t").append(tab).append("<Element>").append(HexDump.toHex(getElement(i))).append("</Element>\n");
-        }
-        builder.append(tab).append("</").append(getClass().getSimpleName()).append(">");
-        return builder.toString();
-    }
-
     /**
      * We have this method because the way in which arrays in escher works
      * is screwed for seemly arbitrary reasons.  While most properties are
@@ -167,8 +195,8 @@ public final class EscherArrayProperty e
      * @return  the number of bytes used by this complex property.
      */
     public int setArrayData(byte[] data, int offset) {
-        if (emptyComplexPart){
-            setComplexData(new byte[0]);
+        if (emptyComplexPart) {
+            resizeComplexData(0);
         } else {
             short numElements = LittleEndian.getShort(data, offset);
             // LittleEndian.getShort(data, offset + 2); // numReserved
@@ -176,13 +204,14 @@ public final class EscherArrayProperty e
 
             // the code here seems to depend on complexData already being
             // sized correctly via the constructor
+            int cdLen = getComplexData().length;
             int arraySize = getActualSizeOfElements(sizeOfElements) * numElements;
-            if (arraySize == getComplexData().length) {
+            if (arraySize == cdLen) {
                 // The stored data size in the simple block excludes the header size
-                setComplexData(new byte[arraySize + 6]);
+                resizeComplexData(arraySize + 6, 0);
                 sizeIncludesHeaderSize = false;
             }
-            System.arraycopy(data, offset, getComplexData(), 0, getComplexData().length );
+            setComplexData(data, offset);
         }
         return getComplexData().length;
     }
@@ -197,7 +226,7 @@ public final class EscherArrayProperty e
     public int serializeSimplePart(byte[] data, int pos) {
         LittleEndian.putShort(data, pos, getId());
         int recordSize = getComplexData().length;
-        if(!sizeIncludesHeaderSize) {
+        if (!sizeIncludesHeaderSize) {
             recordSize -= 6;
         }
         LittleEndian.putInt(data, pos + 2, recordSize);
@@ -238,6 +267,15 @@ public final class EscherArrayProperty e
             }
         };
     }
-    
-    
+
+    @Override
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "base", super::getGenericProperties,
+            "numElements", this::getNumberOfElementsInArray,
+            "numElementsInMemory", this::getNumberOfElementsInMemory,
+            "sizeOfElements", this::getSizeOfElements,
+            "elements", () -> StreamSupport.stream(spliterator(), false).collect(Collectors.toList())
+        );
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java Sat Oct 12 16:32:53 2019
@@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.poi.sl.usermodel.PictureData.PictureType;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 
@@ -39,15 +40,6 @@ public final class EscherBSERecord exten
 
     public static final short RECORD_ID = EscherRecordTypes.BSE.typeID;
 
-    public static final byte BT_ERROR = 0;
-    public static final byte BT_UNKNOWN = 1;
-    public static final byte BT_EMF = 2;
-    public static final byte BT_WMF = 3;
-    public static final byte BT_PICT = 4;
-    public static final byte BT_JPEG = 5;
-    public static final byte BT_PNG = 6;
-    public static final byte BT_DIB = 7;
-
     private byte field_1_blipTypeWin32;
     private byte field_2_blipTypeMacOS;
     private final byte[] field_3_uid = new byte[16];
@@ -164,6 +156,10 @@ public final class EscherBSERecord exten
         return field_1_blipTypeWin32;
     }
 
+    public PictureType getPictureTypeWin32() {
+        return PictureType.forNativeID(field_1_blipTypeWin32);
+    }
+
     /**
      * Set the expected win32 blip type
      * 
@@ -183,6 +179,10 @@ public final class EscherBSERecord exten
         return field_2_blipTypeMacOS;
     }
 
+    public PictureType getPictureTypeMacOS() {
+        return PictureType.forNativeID(field_2_blipTypeMacOS);
+    }
+
     /**
      * Set the expected MacOS blip type
      * 
@@ -363,54 +363,13 @@ public final class EscherBSERecord exten
         _remainingData = (remainingData == null) ? new byte[0] : remainingData.clone();
     }
 
-    /**
-     * Retrieve the string representation given a blip id.
-     * 
-     * @param b the blip type byte-encoded
-     * 
-     * @return the blip type as string
-     */
-    public static String getBlipType(byte b) {
-        switch (b) {
-            case BT_ERROR:   return " ERROR";
-            case BT_UNKNOWN: return " UNKNOWN";
-            case BT_EMF:     return " EMF";
-            case BT_WMF:     return " WMF";
-            case BT_PICT:    return " PICT";
-            case BT_JPEG:    return " JPEG";
-            case BT_PNG:     return " PNG";
-            case BT_DIB:     return " DIB";
-        }
-        if ( b < 32 ) {
-            return " NotKnown";
-        }
-        return " Client";
-    }
-
-    @Override
-    protected Object[][] getAttributeMap() {
-        return new Object[][] {
-            { "BlipTypeWin32", field_1_blipTypeWin32 },
-            { "BlipTypeMacOS", field_2_blipTypeMacOS },
-            { "SUID", field_3_uid },
-            { "Tag", field_4_tag },
-            { "Size", field_5_size },
-            { "Ref", field_6_ref },
-            { "Offset", field_7_offset },
-            { "Usage", field_8_usage },
-            { "Name", field_9_name },
-            { "Unused2", field_10_unused2 },
-            { "Unused3", field_11_unused3 },
-            { "Blip Record", field_12_blipRecord },
-            { "Extra Data", _remainingData }
-        };
-    }
-
     @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         final Map<String, Supplier<?>> m = new LinkedHashMap<>(super.getGenericProperties());
         m.put("blipTypeWin32", this::getBlipTypeWin32);
+        m.put("pictureTypeWin32", this::getPictureTypeWin32);
         m.put("blipTypeMacOS", this::getBlipTypeMacOS);
+        m.put("pictureTypeMacOS", this::getPictureTypeMacOS);
         m.put("suid", this::getUid);
         m.put("tag", this::getTag);
         m.put("size", this::getSize);

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java Sat Oct 12 16:32:53 2019
@@ -17,11 +17,10 @@
 
 package org.apache.poi.ddf;
 
-import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.function.Supplier;
 
+import org.apache.poi.util.GenericRecordUtil;
 import org.apache.poi.util.LittleEndian;
 
 public class EscherBitmapBlip extends EscherBlipRecord {
@@ -114,20 +113,12 @@ public class EscherBitmapBlip extends Es
     }
 
     @Override
-    protected Object[][] getAttributeMap() {
-        return new Object[][] {
-            { "Marker", field_2_marker },
-            { "Extra Data", getPicturedata() }
-        };
-    }
-
-
-    @Override
     public Map<String, Supplier<?>> getGenericProperties() {
-        final Map<String, Supplier<?>> m = new LinkedHashMap<>(super.getGenericProperties());
-        m.put("uid", this::getUID);
-        m.put("marker", this::getMarker);
-        return Collections.unmodifiableMap(m);
+        return GenericRecordUtil.getGenericProperties(
+            "base", super::getGenericProperties,
+            "uid", this::getUID,
+            "marker", this::getMarker
+        );
     }
 
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java Sat Oct 12 16:32:53 2019
@@ -108,13 +108,6 @@ public class EscherBlipRecord extends Es
     }
 
     @Override
-    protected Object[][] getAttributeMap() {
-        return new Object[][] {
-            { "Extra Data", getPicturedata() }
-        };
-    }
-
-    @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
             "base", super::getGenericProperties,

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java Sat Oct 12 16:32:53 2019
@@ -18,8 +18,6 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
-
 /**
  * Represents a boolean property.  The actual utility of this property is in doubt because many
  * of the properties marked as boolean seem to actually contain special values.  In other words
@@ -42,6 +40,18 @@ public class EscherBoolProperty
         super(propertyNumber, value);
     }
 
+
+    /**
+     * Create an instance of an escher boolean property.
+     *
+     * @param propertyType The property type
+     * @param value      The 32 bit value of this bool property
+     */
+    public EscherBoolProperty( EscherPropertyTypes propertyType, int value )
+    {
+        super(propertyType.propNumber, value);
+    }
+
     /**
      * Whether this boolean property is true
      * 
@@ -51,21 +61,4 @@ public class EscherBoolProperty
     {
         return getPropertyValue() != 0;
     }
-
-//    public String toString()
-//    {
-//        return "propNum: " + getPropertyNumber()
-//                + ", complex: " + isComplex()
-//                + ", blipId: " + isBlipId()
-//                + ", value: " + (getValue() != 0);
-//    }
-
-    @Override
-    public String toXml(String tab){
-        StringBuilder builder = new StringBuilder();
-        builder.append(tab).append("<").append(getClass().getSimpleName()).append(" id=\"0x").append(HexDump.toHex(getId()))
-                .append("\" name=\"").append(getName()).append("\" simpleValue=\"").append(getPropertyValue()).append("\" blipId=\"")
-                .append(isBlipId()).append("\" value=\"").append(isTrue()).append("\"").append("/>");
-        return builder.toString();
-    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java Sat Oct 12 16:32:53 2019
@@ -177,16 +177,6 @@ public class EscherChildAnchorRecord ext
     }
 
     @Override
-    protected Object[][] getAttributeMap() {
-        return new Object[][] {
-            { "X1", field_1_dx1 },
-            { "Y1", field_2_dy1 },
-            { "X2", field_3_dx2 },
-            { "Y2", field_4_dy2 }
-        };
-    }
-
-    @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
             "base", super::getGenericProperties,

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java Sat Oct 12 16:32:53 2019
@@ -349,22 +349,6 @@ public class EscherClientAnchorRecord ex
     }
 
     @Override
-    protected Object[][] getAttributeMap() {
-        return new Object[][] {
-            { "Flag", field_1_flag },
-            { "Col1", field_2_col1 },
-            { "DX1", field_3_dx1 },
-            { "Row1", field_4_row1 },
-            { "DY1", field_5_dy1 },
-            { "Col2", field_6_col2 },
-            { "DX2", field_7_dx2 },
-            { "Row2", field_8_row2 },
-            { "DY2", field_9_dy2 },
-            { "Extra Data", remainingData }
-        };
-    }
-
-    @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         final Map<String,Supplier<?>> m = new LinkedHashMap<>(super.getGenericProperties());
         m.put("flag", this::getFlag);

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java Sat Oct 12 16:32:53 2019
@@ -103,13 +103,6 @@ public class EscherClientDataRecord
     }
 
     @Override
-    protected Object[][] getAttributeMap() {
-        return new Object[][] {
-            { "Extra Data", getRemainingData() }
-        };
-    }
-
-    @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
             "base", super::getGenericProperties,

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java Sat Oct 12 16:32:53 2019
@@ -18,9 +18,13 @@
 package org.apache.poi.ddf;
 
 import java.util.Arrays;
+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.IOUtils;
 import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.Removal;
 
 /**
  * A complex property differs from a simple property in that the data can not fit inside a 32 bit
@@ -28,7 +32,10 @@ import org.apache.poi.util.LittleEndian;
  * stored here.
  */
 public class EscherComplexProperty extends EscherProperty {
-    private byte[] _complexData;
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 100_000_000;
+
+    private byte[] complexData;
 
     /**
      * Create a complex property using the property id and a byte array containing the complex
@@ -38,12 +45,11 @@ public class EscherComplexProperty exten
      *                    indicating that this is a complex property.
      * @param complexData The value of this property.
      */
+    @Deprecated
+    @Removal(version = "5.0.0")
     public EscherComplexProperty(short id, byte[] complexData) {
-        super(id);
-        if (complexData == null) {
-            throw new IllegalArgumentException("complexData can't be null");
-        }
-        _complexData = complexData.clone();
+        this(id, complexData == null ? 0 : complexData.length);
+        setComplexData(complexData);
     }
 
     /**
@@ -54,12 +60,48 @@ public class EscherComplexProperty exten
      * @param isBlipId       Whether this is a blip id.  Should be false.
      * @param complexData    The value of this complex property.
      */
+    @Deprecated
+    @Removal(version = "5.0.0")
     public EscherComplexProperty(short propertyNumber, boolean isBlipId, byte[] complexData) {
-        super(propertyNumber, true, isBlipId);
-        if (complexData == null) {
-            throw new IllegalArgumentException("complexData can't be null");
-        }
-        _complexData = complexData.clone();
+        this(propertyNumber, isBlipId, complexData == null ? 0 : complexData.length);
+        setComplexData(complexData);
+    }
+
+    /**
+     * Create a complex property using the property id and a byte array containing the complex
+     * data value size.
+     *
+     * @param id          The id consists of the property number, a flag indicating whether this is a blip id and a flag
+     *                    indicating that this is a complex property.
+     * @param complexSize The byte size of this property.
+     */
+    public EscherComplexProperty(short id, int complexSize) {
+        super((short)(id | IS_COMPLEX));
+        complexData = IOUtils.safelyAllocate(complexSize, MAX_RECORD_LENGTH);
+    }
+
+    /**
+     * Create a complex property using the property number, a flag to indicate whether this is a
+     * blip reference and the complex property data size.
+     *
+     * @param propertyNumber The property number
+     * @param isBlipId       Whether this is a blip id.  Should be false.
+     * @param complexSize    The byte size of this property.
+     */
+    public EscherComplexProperty(short propertyNumber, boolean isBlipId, int complexSize) {
+        this((short)(propertyNumber | (isBlipId ? IS_BLIP : 0)), complexSize);
+    }
+
+    /**
+     * Create a complex property using the property type, a flag to indicate whether this is a
+     * blip reference and the complex property data size.
+     *
+     * @param type           The property type
+     * @param isBlipId       Whether this is a blip id.  Should be false.
+     * @param complexSize    The byte size of this property.
+     */
+    public EscherComplexProperty(EscherPropertyTypes type, boolean isBlipId, int complexSize) {
+        this((short)(type.propNumber | (isBlipId ? IS_BLIP : 0)), complexSize);
     }
 
     /**
@@ -68,7 +110,7 @@ public class EscherComplexProperty exten
     @Override
     public int serializeSimplePart(byte[] data, int pos) {
         LittleEndian.putShort(data, pos, getId());
-        LittleEndian.putInt(data, pos + 2, _complexData.length);
+        LittleEndian.putInt(data, pos + 2, complexData.length);
         return 6;
     }
 
@@ -81,8 +123,8 @@ public class EscherComplexProperty exten
      */
     @Override
     public int serializeComplexPart(byte[] data, int pos) {
-        System.arraycopy(_complexData, 0, data, pos, _complexData.length);
-        return _complexData.length;
+        System.arraycopy(complexData, 0, data, pos, complexData.length);
+        return complexData.length;
     }
 
     /**
@@ -91,11 +133,36 @@ public class EscherComplexProperty exten
      * @return the complex bytes
      */
     public byte[] getComplexData() {
-        return _complexData;
+        return complexData;
+    }
+
+    public int setComplexData(byte[] complexData) {
+        return setComplexData(complexData, 0);
+    }
+
+    public int setComplexData(byte[] complexData, int offset) {
+        if (complexData == null) {
+            return 0;
+        } else {
+            int copySize = Math.max(0, Math.min(this.complexData.length, complexData.length - offset));
+            System.arraycopy(complexData, offset, this.complexData, 0, copySize);
+            return copySize;
+        }
+    }
+
+
+
+    protected void resizeComplexData(int newSize) {
+        resizeComplexData(newSize, Integer.MAX_VALUE);
     }
 
-    protected void setComplexData(byte[] _complexData) {
-        this._complexData = _complexData;
+    protected void resizeComplexData(int newSize, int copyLen) {
+        if (newSize == complexData.length) {
+            return;
+        }
+        byte[] newArray = IOUtils.safelyAllocate(newSize, MAX_RECORD_LENGTH);
+        System.arraycopy(complexData, 0, newArray, 0, Math.min(Math.min(complexData.length, copyLen),newSize));
+        complexData = newArray;
     }
 
     /**
@@ -109,14 +176,13 @@ public class EscherComplexProperty exten
         if (this == o) {
             return true;
         }
-        if (o == null || !(o instanceof EscherComplexProperty)) {
+        if (!(o instanceof EscherComplexProperty)) {
             return false;
         }
 
         EscherComplexProperty escherComplexProperty = (EscherComplexProperty) o;
 
-        return Arrays.equals(_complexData, escherComplexProperty._complexData);
-
+        return Arrays.equals(complexData, escherComplexProperty.complexData);
     }
 
     /**
@@ -126,7 +192,7 @@ public class EscherComplexProperty exten
      */
     @Override
     public int getPropertySize() {
-        return 6 + _complexData.length;
+        return 6 + complexData.length;
     }
 
     @Override
@@ -134,26 +200,11 @@ public class EscherComplexProperty exten
         return getId() * 11;
     }
 
-    /**
-     * Retrieves the string representation for this property.
-     */
-    @Override
-    public String toString() {
-        String dataStr = HexDump.toHex( _complexData, 32);
-
-        return "propNum: " + getPropertyNumber()
-                + ", propName: " + EscherProperties.getPropertyName( getPropertyNumber() )
-                + ", complex: " + isComplex()
-                + ", blipId: " + isBlipId()
-                + ", data: " + System.getProperty("line.separator") + dataStr;
-    }
-
     @Override
-    public String toXml(String tab){
-        return tab + "<" + getClass().getSimpleName() + " id=\"0x" + HexDump.toHex(getId()) +
-                "\" name=\"" + getName() + "\" blipId=\"" +
-                isBlipId() + "\">\n" +
-                tab + "</" + getClass().getSimpleName() + ">";
-        //builder.append("\t").append(tab).append(dataStr);
+    public Map<String, Supplier<?>> getGenericProperties() {
+        return GenericRecordUtil.getGenericProperties(
+            "base", super::getGenericProperties,
+            "data", this::getComplexData
+        );
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java Sat Oct 12 16:32:53 2019
@@ -273,23 +273,6 @@ public final class EscherContainerRecord
     }
 
     @Override
-    protected Object[][] getAttributeMap() {
-        List<Object> chList = new ArrayList<>(_childRecords.size() * 2 + 2);
-        chList.add("children");
-        chList.add(_childRecords.size());
-        int count = 0;
-        for ( EscherRecord record : this ) {
-            chList.add("Child "+count);
-            chList.add(record);
-            count++;
-        }
-        return new Object[][] {
-        	{ "isContainer", isContainerRecord() },
-            chList.toArray()
-        };
-    }
-
-    @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
             "base", super::getGenericProperties,

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java Sat Oct 12 16:32:53 2019
@@ -145,14 +145,6 @@ public class EscherDgRecord extends Esch
     }
 
     @Override
-    protected Object[][] getAttributeMap() {
-        return new Object[][] {
-            { "NumShapes", field_1_numShapes },
-            { "LastMSOSPID", field_2_lastMSOSPID }
-        };
-    }
-
-    @Override
     public Map<String, Supplier<?>> getGenericProperties() {
         return GenericRecordUtil.getGenericProperties(
             "base", super::getGenericProperties,

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java?rev=1868352&r1=1868351&r2=1868352&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java Sat Oct 12 16:32:53 2019
@@ -335,26 +335,6 @@ public final class EscherDggRecord exten
         
         return shapeId;
     }    
-    
-    
-    @Override
-    protected Object[][] getAttributeMap() {
-        List<Object> fldIds = new ArrayList<>();
-        fldIds.add("FileId Clusters");
-        fldIds.add(field_5_fileIdClusters.size());
-        for (FileIdCluster fic : field_5_fileIdClusters) {
-            fldIds.add("Group"+fic.field_1_drawingGroupId);
-            fldIds.add(fic.field_2_numShapeIdsUsed);
-        }
-        
-        return new Object[][] {
-            { "ShapeIdMax", field_1_shapeIdMax },
-            { "NumIdClusters", getNumIdClusters() },
-            { "NumShapesSaved", field_3_numShapesSaved },
-            { "DrawingsSaved", field_4_drawingsSaved },
-            fldIds.toArray()
-        };
-    }
 
     @Override
     public Enum getGenericRecordType() {



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