Author: kiwiwings
Date: Fri Jun 30 20:21:33 2017
New Revision: 1800452

URL: http://svn.apache.org/viewvc?rev=1800452&view=rev
Log:
#61243 - Refactor and unify toString/toXml in DDF

Modified:
    poi/site/src/documentation/content/xdocs/status.xml
    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/EscherColorRef.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/EscherOptRecord.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java
    poi/trunk/src/java/org/apache/poi/ddf/EscherProperty.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/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/scratchpad/src/org/apache/poi/hslf/record/EscherPlaceholder.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/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

Modified: poi/site/src/documentation/content/xdocs/status.xml
URL: 
http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/status.xml?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/status.xml (original)
+++ poi/site/src/documentation/content/xdocs/status.xml Fri Jun 30 20:21:33 2017
@@ -58,6 +58,7 @@
 
     <release version="3.17-beta2" date="2017-09-??">
        <actions>
+               <action dev="PD" type="fix" fixes-bug="61243" module="POI 
Overall">Refactor and unify toString/toXml in DDF</action>
                <action dev="PD" type="fix" fixes-bug="61182" 
module="OPC">Invalid signature created for streamed xslx file</action>
        </actions>
     </release>
@@ -352,7 +353,7 @@
         <action dev="PD" type="fix" fixes-bug="56930" module="SS Common">Add 
Workbook.getNames() to allow to query for names that appear multiple 
times</action>
         <action dev="PD" type="fix" fixes-bug="55791">Avoid using an existing 
file-name when creating a new slide, it could still be left over from previous 
partial removal</action>
         <action dev="PD" type="fix" fixes-bug="55668" module="SS Common">Try 
to avoid NullPointerException by setting the cell to BLANK instead, when 
changing cell-type and a formula leads to null-string</action>
-        <action dev="PD" type="fix" fixes-bug="59135">Password gets truncated 
when using passwords longer than 15 characters for the function 
protectSheet()</action> 
+        <action dev="PD" type="fix" fixes-bug="59135">Password gets truncated 
when using passwords longer than 15 characters for the function 
protectSheet()</action>
         <action dev="PD" type="add" fixes-bug="56549" module="HWPF">Correctly 
calculate char index ranges for HWPF in the TextPieceTable</action>
         <action dev="PD" type="add" fixes-bug="57495">Fix problem with tables 
in documents at pos 0</action>
         <action dev="PD" type="fix">Fix a number of edge-cases where 
file-handles would be leaked</action>

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ddf/AbstractEscherOptRecord.java Fri Jun 
30 20:21:33 2017
@@ -22,7 +22,6 @@ import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -175,53 +174,20 @@ public abstract class AbstractEscherOptR
         }
     }
 
-    /**
-     * Retrieve the string representation of this record.
-     */
     @Override
-    public String toString()
-    {
-        String nl = System.getProperty( "line.separator" );
-
-        StringBuilder stringBuilder = new StringBuilder();
-        stringBuilder.append( getClass().getName() );
-        stringBuilder.append( ":" );
-        stringBuilder.append( nl );
-        stringBuilder.append( "  isContainer: " );
-        stringBuilder.append( isContainerRecord() );
-        stringBuilder.append( nl );
-        stringBuilder.append( "  version: 0x" );
-        stringBuilder.append( HexDump.toHex( getVersion() ) );
-        stringBuilder.append( nl );
-        stringBuilder.append( "  instance: 0x" );
-        stringBuilder.append( HexDump.toHex( getInstance() ) );
-        stringBuilder.append( nl );
-        stringBuilder.append( "  recordId: 0x" );
-        stringBuilder.append( HexDump.toHex( getRecordId() ) );
-        stringBuilder.append( nl );
-        stringBuilder.append( "  numchildren: " );
-        stringBuilder.append( getChildRecords().size() );
-        stringBuilder.append( nl );
-        stringBuilder.append( "  properties:" );
-        stringBuilder.append( nl );
-
-        for ( EscherProperty property : properties )
-        {
-            stringBuilder.append("    ").append(property).append(nl);
-        }
-
-        return stringBuilder.toString();
-    }
-
-    @Override
-    public String toXml(String tab) {
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(),
-                HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())));
-        for (EscherProperty property: getEscherProperties()){
-            builder.append(property.toXml(tab+"\t"));
-        }
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
+    protected Object[][] getAttributeMap() {
+        List<Object> attrList = new ArrayList<Object>(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()
+        };
     }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherArrayProperty.java Fri Jun 30 
20:21:33 2017
@@ -121,6 +121,11 @@ public final class EscherArrayProperty e
     @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');
@@ -130,11 +135,7 @@ public final class EscherArrayProperty e
         }
         results.append("}" + '\n');
 
-        return "propNum: " + getPropertyNumber()
-                + ", propName: " + EscherProperties.getPropertyName( 
getPropertyNumber() )
-                + ", complex: " + isComplex()
-                + ", blipId: " + isBlipId()
-                + ", data: " + '\n' + results;
+        return results.toString();
     }
 
     @Override
@@ -146,7 +147,7 @@ public final class EscherArrayProperty e
         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(">\n");
+        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">");
         return builder.toString();
     }
 
@@ -220,7 +221,9 @@ public final class EscherArrayProperty e
             
             @Override
             public byte[] next() {
-                if (!hasNext()) throw new NoSuchElementException();
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
                 return getElement(idx++);
             }
             

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBSERecord.java Fri Jun 30 
20:21:33 2017
@@ -17,11 +17,10 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 /**
- * The BSE record is related closely to the <code>EscherBlipRecord</code> and 
stores
+ * The BSE record is related closely to the {@code EscherBlipRecord} and stores
  * extra information about the blip.  A blip record is actually stored inside
  * the BSE record even though the BSE record isn't actually a container record.
  *
@@ -55,6 +54,10 @@ public final class EscherBSERecord exten
 
     private byte[] _remainingData = new byte[0];
 
+    public EscherBSERecord() {
+        setRecordId(RECORD_ID);
+    }
+    
     @Override
     public int fillFields(byte[] data, int offset, EscherRecordFactory 
recordFactory) {
         int bytesRemaining = readHeader( data, offset );
@@ -103,8 +106,7 @@ public final class EscherBSERecord exten
 
         data[offset + 8] = field_1_blipTypeWin32;
         data[offset + 9] = field_2_blipTypeMacOS;
-        for ( int i = 0; i < 16; i++ )
-            data[offset + 10 + i] = field_3_uid[i];
+        System.arraycopy(field_3_uid, 0, data, offset + 10, 16);
         LittleEndian.putShort( data, offset + 26, field_4_tag );
         LittleEndian.putInt( data, offset + 28, field_5_size );
         LittleEndian.putInt( data, offset + 32, field_6_ref );
@@ -114,8 +116,7 @@ public final class EscherBSERecord exten
         data[offset + 42] = field_10_unused2;
         data[offset + 43] = field_11_unused3;
         int bytesWritten = 0;
-        if (field_12_blipRecord != null)
-        {
+        if (field_12_blipRecord != null) {
             bytesWritten = field_12_blipRecord.serialize( offset + 44, data, 
new NullEscherSerializationListener() );
         }
         System.arraycopy( _remainingData, 0, data, offset + 44 + bytesWritten, 
_remainingData.length );
@@ -350,52 +351,7 @@ public final class EscherBSERecord exten
      * @param remainingData the remaining bytes
      */
     public void setRemainingData(byte[] remainingData) {
-        if (remainingData == null) {
-            _remainingData = new byte[0];
-        } else {
-            _remainingData = remainingData.clone();
-        }
-    }
-
-    @Override
-    public String toString() {
-        String extraData = _remainingData == null ? null : 
HexDump.toHex(_remainingData, 32);
-        return getClass().getName() + ":" + '\n' +
-                "  RecordId: 0x" + HexDump.toHex( RECORD_ID ) + '\n' +
-                "  Version: 0x" + HexDump.toHex( getVersion() ) + '\n' +
-                "  Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' +
-                "  BlipTypeWin32: " + field_1_blipTypeWin32 + '\n' +
-                "  BlipTypeMacOS: " + field_2_blipTypeMacOS + '\n' +
-                "  SUID: " + (field_3_uid == null ? "" : 
HexDump.toHex(field_3_uid)) + '\n' +
-                "  Tag: " + field_4_tag + '\n' +
-                "  Size: " + field_5_size + '\n' +
-                "  Ref: " + field_6_ref + '\n' +
-                "  Offset: " + field_7_offset + '\n' +
-                "  Usage: " + field_8_usage + '\n' +
-                "  Name: " + field_9_name + '\n' +
-                "  Unused2: " + field_10_unused2 + '\n' +
-                "  Unused3: " + field_11_unused3 + '\n' +
-                "  blipRecord: " + field_12_blipRecord + '\n' +
-                "  Extra Data:" + '\n' + extraData;
-    }
-
-    @Override
-    public String toXml(String tab) {
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<BlipTypeWin32>").append(field_1_blipTypeWin32).append("</BlipTypeWin32>\n")
-                
.append(tab).append("\t").append("<BlipTypeMacOS>").append(field_2_blipTypeMacOS).append("</BlipTypeMacOS>\n")
-                .append(tab).append("\t").append("<SUID>").append(field_3_uid 
== null ? "" : HexDump.toHex(field_3_uid)).append("</SUID>\n")
-                
.append(tab).append("\t").append("<Tag>").append(field_4_tag).append("</Tag>\n")
-                
.append(tab).append("\t").append("<Size>").append(field_5_size).append("</Size>\n")
-                
.append(tab).append("\t").append("<Ref>").append(field_6_ref).append("</Ref>\n")
-                
.append(tab).append("\t").append("<Offset>").append(field_7_offset).append("</Offset>\n")
-                
.append(tab).append("\t").append("<Usage>").append(field_8_usage).append("</Usage>\n")
-                
.append(tab).append("\t").append("<Name>").append(field_9_name).append("</Name>\n")
-                
.append(tab).append("\t").append("<Unused2>").append(field_10_unused2).append("</Unused2>\n")
-                
.append(tab).append("\t").append("<Unused3>").append(field_11_unused3).append("</Unused3>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
+        _remainingData = (remainingData == null) ? new byte[0] : 
remainingData.clone();
     }
 
     /**
@@ -421,4 +377,23 @@ public final class EscherBSERecord exten
         }
         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 }
+        };
+    }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBitmapBlip.java Fri Jun 30 
20:21:33 2017
@@ -17,7 +17,6 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 public class EscherBitmapBlip extends EscherBlipRecord {
@@ -110,29 +109,10 @@ public class EscherBitmapBlip extends Es
     }
 
     @Override
-    public String toString() {
-        String nl = System.getProperty( "line.separator" );
-
-        String extraData = HexDump.dump(getPicturedata(), 0, 0);
-
-        return getClass().getName() + ":" + nl +
-            "  RecordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
-            "  Version: 0x" + HexDump.toHex( getVersion() ) + nl +
-            "  Instance: 0x" + HexDump.toHex( getInstance() ) + nl +
-            "  UID: 0x" + HexDump.toHex( field_1_UID ) + nl +
-            "  Marker: 0x" + HexDump.toHex( field_2_marker ) + nl +
-            "  Extra Data:" + nl + extraData;
-    }
-
-    @Override
-    public String toXml(String tab) {
-        String extraData = HexDump.dump(getPicturedata(), 0, 0);
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-            
.append(tab).append("\t").append("<UID>0x").append(HexDump.toHex(field_1_UID)).append("</UID>\n")
-            
.append(tab).append("\t").append("<Marker>0x").append(HexDump.toHex(field_2_marker)).append("</Marker>\n")
-            
.append(tab).append("\t").append("<ExtraData>").append(extraData).append("</ExtraData>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
+    protected Object[][] getAttributeMap() {
+        return new Object[][] {
+            { "Marker", field_2_marker },
+            { "Extra Data", getPicturedata() }
+        };
     }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBlipRecord.java Fri Jun 30 
20:21:33 2017
@@ -18,7 +18,6 @@
 package org.apache.poi.ddf;
 
 import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.HexDump;
 
 public class EscherBlipRecord extends EscherRecord {
     public static final short  RECORD_ID_START    = (short) 0xF018;
@@ -100,22 +99,9 @@ public class EscherBlipRecord extends Es
     }
 
     @Override
-    public String toString() {
-        String extraData = HexDump.toHex(field_pictureData, 32);
-        return getClass().getName() + ":" + '\n' +
-                "  RecordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' +
-                "  Version: 0x" + HexDump.toHex( getVersion() ) + '\n' +
-                "  Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' +
-                "  Extra Data:" + '\n' + extraData;
-    }
-
-    @Override
-    public String toXml(String tab) {
-        String extraData = HexDump.toHex(field_pictureData, 32);
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<ExtraData>").append(extraData).append("</ExtraData>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
+    protected Object[][] getAttributeMap() {
+        return new Object[][] {
+            { "Extra Data", getPicturedata() }
+        };
     }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherBoolProperty.java Fri Jun 30 
20:21:33 2017
@@ -59,6 +59,7 @@ public class EscherBoolProperty
      * 
      * @deprecated use !isTrue() instead, planed to be removed in POI 3.17
      */
+    @Deprecated
     public boolean isFalse()
     {
         return !isTrue();
@@ -77,7 +78,7 @@ public class EscherBoolProperty
         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("/>\n");
+                .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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherChildAnchorRecord.java Fri Jun 
30 20:21:33 2017
@@ -18,7 +18,6 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -97,37 +96,6 @@ public class EscherChildAnchorRecord
 
 
     /**
-     * The string representation of this record
-     */
-    @Override
-    public String toString()
-    {
-        String nl = System.getProperty("line.separator");
-
-        return getClass().getName() + ":" + nl +
-                "  RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
-                "  Version: 0x" + HexDump.toHex(getVersion()) + nl +
-                "  Instance: 0x" + HexDump.toHex(getInstance()) + nl +
-                "  X1: " + field_1_dx1 + nl +
-                "  Y1: " + field_2_dy1 + nl +
-                "  X2: " + field_3_dx2 + nl +
-                "  Y2: " + field_4_dy2 + nl ;
-
-    }
-
-    @Override
-    public String toXml(String tab) {
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<X1>").append(field_1_dx1).append("</X1>\n")
-                
.append(tab).append("\t").append("<Y1>").append(field_2_dy1).append("</Y1>\n")
-                
.append(tab).append("\t").append("<X2>").append(field_3_dx2).append("</X2>\n")
-                
.append(tab).append("\t").append("<Y2>").append(field_4_dy2).append("</Y2>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
-    }
-
-    /**
      * Retrieves offset within the parent coordinate space for the top left 
point.
      * 
      * @return the x offset of the top left point
@@ -207,4 +175,13 @@ public class EscherChildAnchorRecord
         this.field_4_dy2 = field_4_dy2;
     }
 
+    @Override
+    protected Object[][] getAttributeMap() {
+        return new Object[][] {
+            { "X1", field_1_dx1 },
+            { "Y1", field_2_dy1 },
+            { "X2", field_3_dx2 },
+            { "Y2", field_4_dy2 }
+        };
+    }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherClientAnchorRecord.java Fri Jun 
30 20:21:33 2017
@@ -17,7 +17,6 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -94,7 +93,9 @@ public class EscherClientAnchorRecord
     {
         listener.beforeRecordSerialize( offset, getRecordId(), this );
 
-        if (remainingData == null) remainingData = new byte[0];
+        if (remainingData == null) {
+            remainingData = new byte[0];
+        }
         LittleEndian.putShort( data, offset, getOptions() );
         LittleEndian.putShort( data, offset + 2, getRecordId() );
         int remainingBytes = remainingData.length + (shortRecord ? 8 : 18);
@@ -134,52 +135,8 @@ public class EscherClientAnchorRecord
     }
 
     /**
-     * Returns the string representation for this record.
-     *
-     * @return A string
-     */
-    @Override
-    public String toString()
-    {
-        String nl = System.getProperty("line.separator");
-        String extraData = HexDump.dump(this.remainingData, 0, 0);
-        return getClass().getName() + ":" + nl +
-                "  RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
-                "  Version: 0x" + HexDump.toHex(getVersion()) + nl +
-                "  Instance: 0x" + HexDump.toHex(getInstance()) + nl +
-                "  Flag: " + field_1_flag + nl +
-                "  Col1: " + field_2_col1 + nl +
-                "  DX1: " + field_3_dx1 + nl +
-                "  Row1: " + field_4_row1 + nl +
-                "  DY1: " + field_5_dy1 + nl +
-                "  Col2: " + field_6_col2 + nl +
-                "  DX2: " + field_7_dx2 + nl +
-                "  Row2: " + field_8_row2 + nl +
-                "  DY2: " + field_9_dy2 + nl +
-                "  Extra Data:" + nl + extraData;
-
-    }
-
-    @Override
-    public String toXml(String tab) {
-        String extraData = HexDump.dump(this.remainingData, 0, 0).trim();
-        return tab + formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())) +
-                tab + "\t" + "<Flag>" + field_1_flag + "</Flag>\n" +
-                tab + "\t" + "<Col1>" + field_2_col1 + "</Col1>\n" +
-                tab + "\t" + "<DX1>" + field_3_dx1 + "</DX1>\n" +
-                tab + "\t" + "<Row1>" + field_4_row1 + "</Row1>\n" +
-                tab + "\t" + "<DY1>" + field_5_dy1 + "</DY1>\n" +
-                tab + "\t" + "<Col2>" + field_6_col2 + "</Col2>\n" +
-                tab + "\t" + "<DX2>" + field_7_dx2 + "</DX2>\n" +
-                tab + "\t" + "<Row2>" + field_8_row2 + "</Row2>\n" +
-                tab + "\t" + "<DY2>" + field_9_dy2 + "</DY2>\n" +
-                tab + "\t" + "<ExtraData>" + extraData + "</ExtraData>\n" +
-                tab + "</" + getClass().getSimpleName() + ">\n";
-    }
-
-    /**
      * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = 
Don't move or size with cells.
-     * 
+     *
      * @return the move/size flag
      */
     public short getFlag()
@@ -189,7 +146,7 @@ public class EscherClientAnchorRecord
 
     /**
      * 0 = Move and size with Cells, 2 = Move but don't size with cells, 3 = 
Don't move or size with cells.
-     * 
+     *
      * @param field_1_flag the move/size flag
      */
     public void setFlag( short field_1_flag )
@@ -199,7 +156,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The column number for the top-left position.  0 based.
-     * 
+     *
      * @return the column number of the top-left corner
      */
     public short getCol1()
@@ -209,7 +166,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The column number for the top-left position.  0 based.
-     * 
+     *
      * @param field_2_col1 the column number of the top-left corner
      */
     public void setCol1( short field_2_col1 )
@@ -219,7 +176,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The x offset within the top-left cell.  Range is from 0 to 1023.
-     * 
+     *
      * @return the x offset of the top-left corner
      */
     public short getDx1()
@@ -229,7 +186,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The x offset within the top-left cell.  Range is from 0 to 1023.
-     * 
+     *
      * @param field_3_dx1 the x offset of the top-left corner
      */
     public void setDx1( short field_3_dx1 )
@@ -239,7 +196,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The row number for the top-left corner of the shape.
-     * 
+     *
      * @return the row number of the top-left corner
      */
     public short getRow1()
@@ -249,7 +206,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The row number of the top-left corner of the shape.
-     * 
+     *
      * @param field_4_row1 the row number of the top-left corner
      */
     public void setRow1( short field_4_row1 )
@@ -259,7 +216,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The y offset within the top-left corner of the current shape.
-     * 
+     *
      * @return the y offset of the top-left corner
      */
     public short getDy1()
@@ -269,7 +226,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The y offset within the top-left corner of the current shape.
-     * 
+     *
      * @param field_5_dy1 the y offset of the top-left corner
      */
     public void setDy1( short field_5_dy1 )
@@ -280,7 +237,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The column of the bottom right corner of this shape.
-     * 
+     *
      * @return the column of the bottom right corner
      */
     public short getCol2()
@@ -290,7 +247,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The column of the bottom right corner of this shape.
-     * 
+     *
      * @param field_6_col2 the column of the bottom right corner
      */
     public void setCol2( short field_6_col2 )
@@ -301,7 +258,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The x offset withing the cell for the bottom-right corner of this shape.
-     * 
+     *
      * @return the x offset of the bottom-right corner
      */
     public short getDx2()
@@ -311,7 +268,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The x offset withing the cell for the bottom-right corner of this shape.
-     * 
+     *
      * @param field_7_dx2 the x offset of the bottom-right corner
      */
     public void setDx2( short field_7_dx2 )
@@ -322,7 +279,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The row number for the bottom-right corner of the current shape.
-     * 
+     *
      * @return the row number for the bottom-right corner
      */
     public short getRow2()
@@ -332,7 +289,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The row number for the bottom-right corner of the current shape.
-     * 
+     *
      * @param field_8_row2 the row number for the bottom-right corner
      */
     public void setRow2( short field_8_row2 )
@@ -343,7 +300,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The y offset withing the cell for the bottom-right corner of this shape.
-     * 
+     *
      * @return the y offset of the bottom-right corner
      */
     public short getDy2()
@@ -353,7 +310,7 @@ public class EscherClientAnchorRecord
 
     /**
      * The y offset withing the cell for the bottom-right corner of this shape.
-     * 
+     *
      * @param field_9_dy2 the y offset of the bottom-right corner
      */
     public void setDy2( short field_9_dy2 )
@@ -364,7 +321,7 @@ public class EscherClientAnchorRecord
 
     /**
      * Any remaining data in the record
-     * 
+     *
      * @return the remaining bytes
      */
     public byte[] getRemainingData()
@@ -374,7 +331,7 @@ public class EscherClientAnchorRecord
 
     /**
      * Any remaining data in the record
-     * 
+     *
      * @param remainingData the remaining bytes
      */
     public void setRemainingData( byte[] remainingData ) {
@@ -384,4 +341,20 @@ public class EscherClientAnchorRecord
             this.remainingData = remainingData.clone();
         }
     }
+
+    @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 }
+        };
+    }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherClientDataRecord.java Fri Jun 
30 20:21:33 2017
@@ -18,7 +18,6 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -46,7 +45,9 @@ public class EscherClientDataRecord
     public int serialize(int offset, byte[] data, EscherSerializationListener 
listener) {
         listener.beforeRecordSerialize( offset, getRecordId(), this );
 
-        if (remainingData == null) remainingData = new byte[0];
+        if (remainingData == null) {
+            remainingData = new byte[0];
+        }
         LittleEndian.putShort( data, offset, getOptions() );
         LittleEndian.putShort( data, offset + 2, getRecordId() );
         LittleEndian.putInt( data, offset + 4, remainingData.length );
@@ -74,34 +75,6 @@ public class EscherClientDataRecord
     }
 
     /**
-     * Returns the string representation of this record.
-     */
-    @Override
-    public String toString()
-    {
-        String nl = System.getProperty("line.separator");
-        String extraData = HexDump.dump(getRemainingData(), 0, 0);
-        return getClass().getName() + ":" + nl +
-                "  RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
-                "  Version: 0x" + HexDump.toHex(getVersion()) + nl +
-                "  Instance: 0x" + HexDump.toHex(getInstance()) + nl +
-                "  Extra Data:" + nl +
-                extraData;
-
-    }
-
-    @Override
-    public String toXml(String tab) {
-        String extraData = HexDump.dump(getRemainingData(), 0, 0).trim();
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()),
-                HexDump.toHex(getVersion()), HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<ExtraData>").append(extraData).append("</ExtraData>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
-    }
-
-    /**
      * Any data recording this record.
      * 
      * @return the remaining bytes
@@ -121,4 +94,11 @@ public class EscherClientDataRecord
             ? new byte[0]
             : remainingData.clone();
     }
+
+    @Override
+    protected Object[][] getAttributeMap() {
+        return new Object[][] {
+            { "Extra Data", getRemainingData() }
+        };
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherColorRef.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherColorRef.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherColorRef.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherColorRef.java Fri Jun 30 
20:21:33 2017
@@ -230,10 +230,14 @@ public class EscherColorRef {
      * @return {@link SysIndexSource} if {@link #hasSysIndexFlag()} is {@code 
true}, otherwise null
      */
     public SysIndexSource getSysIndexSource() {
-        if (!hasSysIndexFlag()) return null;
+        if (!hasSysIndexFlag()) {
+            return null;
+        }
         int val = FLAG_RED.getValue(colorRef);
         for (SysIndexSource sis : SysIndexSource.values()) {
-            if (sis.value == val) return sis;
+            if (sis.value == val) {
+                return sis;
+            }
         }
         return null;
     }
@@ -243,11 +247,17 @@ public class EscherColorRef {
      * @return {@link SysIndexProcedure} if {@link #hasSysIndexFlag()} is 
{@code true}, otherwise null
      */
     public SysIndexProcedure getSysIndexProcedure() {
-        if (!hasSysIndexFlag()) return null;
+        if (!hasSysIndexFlag()) {
+            return null;
+        }
         int val = FLAG_GREEN.getValue(colorRef);
         for (SysIndexProcedure sip : SysIndexProcedure.values()) {
-            if (sip == SysIndexProcedure.INVERT_AFTER || sip == 
SysIndexProcedure.INVERT_HIGHBIT_AFTER) continue;
-            if (sip.mask.isSet(val)) return sip;
+            if (sip == SysIndexProcedure.INVERT_AFTER || sip == 
SysIndexProcedure.INVERT_HIGHBIT_AFTER) {
+                continue;
+            }
+            if (sip.mask.isSet(val)) {
+                return sip;
+            }
         }
         return null;
     }
@@ -257,10 +267,16 @@ public class EscherColorRef {
      * 2 for {@link SysIndexProcedure#INVERT_HIGHBIT_AFTER} 
      */
     public int getSysIndexInvert() {
-        if (!hasSysIndexFlag()) return 0;
+        if (!hasSysIndexFlag()) {
+            return 0;
+        }
         int val = FLAG_GREEN.getValue(colorRef);
-        if ((SysIndexProcedure.INVERT_AFTER.mask.isSet(val))) return 1;
-        if ((SysIndexProcedure.INVERT_HIGHBIT_AFTER.mask.isSet(val))) return 2;
+        if ((SysIndexProcedure.INVERT_AFTER.mask.isSet(val))) {
+            return 1;
+        }
+        if ((SysIndexProcedure.INVERT_HIGHBIT_AFTER.mask.isSet(val))) {
+            return 2;
+        }
         return 0;
     }
     
@@ -270,7 +286,9 @@ public class EscherColorRef {
      * @see org.apache.poi.hslf.record.ColorSchemeAtom#getColor(int)
      */
     public int getSchemeIndex() {
-        if (!hasSchemeIndexFlag()) return -1;
+        if (!hasSchemeIndexFlag()) {
+            return -1;
+        }
         return FLAG_RED.getValue(colorRef);
     }
     

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherComplexProperty.java Fri Jun 30 
20:21:33 2017
@@ -153,7 +153,7 @@ public class EscherComplexProperty exten
         return tab + "<" + getClass().getSimpleName() + " id=\"0x" + 
HexDump.toHex(getId()) +
                 "\" name=\"" + getName() + "\" blipId=\"" +
                 isBlipId() + "\">\n" +
-                tab + "</" + getClass().getSimpleName() + ">\n";
+                tab + "</" + getClass().getSimpleName() + ">";
         //builder.append("\t").append(tab).append(dataStr);
     }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java Fri Jun 30 
20:21:33 2017
@@ -126,9 +126,9 @@ public final class EscherContainerRecord
 
     /**
      * Do any of our (top level) children have the given recordId?
-     * 
+     *
      * @param recordId the recordId of the child
-     * 
+     *
      * @return true, if any child has the given recordId
      */
     public boolean hasChildOfType(short recordId) {
@@ -162,7 +162,7 @@ public final class EscherContainerRecord
     public Iterator<EscherRecord> getChildIterator() {
         return iterator();
     }
-    
+
     /**
      * @return an iterator over the child records
      */
@@ -198,7 +198,7 @@ public final class EscherContainerRecord
     /**
      * Returns all of our children which are also
      * EscherContainers (may be 0, 1, or vary rarely 2 or 3)
-     * 
+     *
      * @return EscherContainer children
      */
     public List<EscherContainerRecord> getChildContainers() {
@@ -266,48 +266,6 @@ public final class EscherContainerRecord
         _childRecords.add(idx, record);
     }
 
-    @Override
-    public String toString()
-    {
-        String nl = System.getProperty( "line.separator" );
-
-        StringBuffer children = new StringBuffer();
-        if ( _childRecords.size() > 0 )
-        {
-            children.append( "  children: " + nl );
-
-            int count = 0;
-            for ( EscherRecord record : this ) {
-                children.append( "   Child " + count + ":" + nl );
-                String childResult = String.valueOf( record );
-                childResult = childResult.replaceAll( "\n", "\n    " );
-                children.append( "    " );
-                children.append( childResult );
-                children.append( nl );
-                count++;
-            }
-        }
-
-        return getClass().getName() + " (" + getRecordName() + "):" + nl
-                + "  isContainer: " + isContainerRecord() + nl
-                + "  version: 0x" + HexDump.toHex( getVersion() ) + nl
-                + "  instance: 0x" + HexDump.toHex( getInstance() ) + nl
-                + "  recordId: 0x" + HexDump.toHex( getRecordId() ) + nl
-                + "  numchildren: " + _childRecords.size() + nl
-                + children;
-    }
-
-    @Override
-    public String toXml(String tab) {
-        StringBuilder builder = new StringBuilder();
-        builder.append(tab).append(formatXmlRecordHeader(getRecordName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())));
-        for ( EscherRecord record : this ) {
-            builder.append(record.toXml(tab+"\t"));
-        }
-        builder.append(tab).append("</").append(getRecordName()).append(">\n");
-        return builder.toString();
-    }
-
     public <T extends EscherRecord> T getChildById( short recordId ) {
         for ( EscherRecord childRecord : this ) {
             if ( childRecord.getRecordId() == recordId ) {
@@ -335,4 +293,21 @@ public final class EscherContainerRecord
             }
         }
     }
+
+    @Override
+    protected Object[][] getAttributeMap() {
+        List<Object> chList = new ArrayList<Object>(_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()
+        };
+    }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherDgRecord.java Fri Jun 30 
20:21:33 2017
@@ -18,7 +18,6 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndian;
 
 /**
@@ -86,29 +85,6 @@ public class EscherDgRecord
     }
 
     /**
-     * Returns the string representation of this record.
-     */
-    @Override
-    public String toString() {
-        return getClass().getName() + ":" + '\n' +
-                "  RecordId: 0x" + HexDump.toHex(RECORD_ID) + '\n' +
-                "  Version: 0x" + HexDump.toHex(getVersion()) + '\n' +
-                "  Instance: 0x" + HexDump.toHex(getInstance()) + '\n' +
-                "  NumShapes: " + field_1_numShapes + '\n' +
-                "  LastMSOSPID: " + field_2_lastMSOSPID + '\n';
-    }
-
-    @Override
-    public String toXml(String tab) {
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<NumShapes>").append(field_1_numShapes).append("</NumShapes>\n")
-                
.append(tab).append("\t").append("<LastMSOSPID>").append(field_2_lastMSOSPID).append("</LastMSOSPID>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
-    }
-
-    /**
      * The number of shapes in this drawing group.
      * 
      * @return the number of shapes
@@ -166,4 +142,12 @@ public class EscherDgRecord
     {
         this.field_1_numShapes++;
     }
+
+    @Override
+    protected Object[][] getAttributeMap() {
+        return new Object[][] {
+            { "NumShapes", field_1_numShapes },
+            { "LastMSOSPID", field_2_lastMSOSPID }
+        };
+    }
 }

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=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherDggRecord.java Fri Jun 30 
20:21:33 2017
@@ -17,12 +17,15 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.RecordFormatException;
 
-import java.util.*;
-
 /**
  * This record defines the drawing groups used for a particular sheet.
  */
@@ -82,8 +85,9 @@ public final class EscherDggRecord exten
             size += 8;
         }
         bytesRemaining         -= size;
-        if (bytesRemaining != 0)
+        if (bytesRemaining != 0) {
             throw new RecordFormatException("Expecting no remaining data but 
got " + bytesRemaining + " byte(s).");
+        }
         return 8 + size + bytesRemaining;
     }
 
@@ -125,42 +129,6 @@ public final class EscherDggRecord exten
         return "Dgg";
     }
 
-    @Override
-    public String toString() {
-
-        StringBuilder field_5_string = new StringBuilder();
-        if(field_5_fileIdClusters != null) for (int i = 0; i < 
field_5_fileIdClusters.length; i++) {
-            field_5_string.append("  DrawingGroupId").append(i+1).append(": ");
-            
field_5_string.append(field_5_fileIdClusters[i].field_1_drawingGroupId);
-            field_5_string.append('\n');
-            field_5_string.append("  NumShapeIdsUsed").append(i+1).append(": 
");
-            
field_5_string.append(field_5_fileIdClusters[i].field_2_numShapeIdsUsed);
-            field_5_string.append('\n');
-        }
-        return getClass().getName() + ":" + '\n' +
-                "  RecordId: 0x" + HexDump.toHex(RECORD_ID) + '\n' +
-                "  Version: 0x" + HexDump.toHex(getVersion()) + '\n' +
-                "  Instance: 0x" + HexDump.toHex(getInstance()) + '\n' +
-                "  ShapeIdMax: " + field_1_shapeIdMax + '\n' +
-                "  NumIdClusters: " + getNumIdClusters() + '\n' +
-                "  NumShapesSaved: " + field_3_numShapesSaved + '\n' +
-                "  DrawingsSaved: " + field_4_drawingsSaved + '\n' +
-                "" + field_5_string;
-
-    }
-
-    @Override
-    public String toXml(String tab) {
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<ShapeIdMax>").append(field_1_shapeIdMax).append("</ShapeIdMax>\n")
-                
.append(tab).append("\t").append("<NumIdClusters>").append(getNumIdClusters()).append("</NumIdClusters>\n")
-                
.append(tab).append("\t").append("<NumShapesSaved>").append(field_3_numShapesSaved).append("</NumShapesSaved>\n")
-                
.append(tab).append("\t").append("<DrawingsSaved>").append(field_4_drawingsSaved).append("</DrawingsSaved>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
-    }
-
     /**
      * Gets the next available shape id
      *
@@ -280,7 +248,9 @@ public final class EscherDggRecord exten
     public void addCluster( int dgId, int numShapedUsed, boolean sort ) {
         List<FileIdCluster> clusters = new 
ArrayList<FileIdCluster>(Arrays.asList(field_5_fileIdClusters));
         clusters.add(new FileIdCluster(dgId, numShapedUsed));
-        if(sort) Collections.sort(clusters, MY_COMP );
+        if(sort) {
+            Collections.sort(clusters, MY_COMP );
+        }
         maxDgId = Math.min(maxDgId, dgId);
         field_5_fileIdClusters = clusters.toArray( new 
FileIdCluster[clusters.size()] );
     }
@@ -297,4 +267,25 @@ public final class EscherDggRecord exten
             return +1;
         }
     };
+
+    @Override
+    protected Object[][] getAttributeMap() {
+        List<Object> fldIds = new ArrayList<Object>();
+        fldIds.add("FileId Clusters");
+        fldIds.add(field_5_fileIdClusters.length);
+        if(field_5_fileIdClusters != null) {
+            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()
+        };
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherDump.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherDump.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherDump.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherDump.java Fri Jun 30 20:21:33 
2017
@@ -17,16 +17,16 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
-import org.apache.poi.util.HexRead;
-import org.apache.poi.util.LittleEndian;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
 import java.util.zip.InflaterInputStream;
 
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.HexRead;
+import org.apache.poi.util.LittleEndian;
+
 /**
  * Used to dump the contents of escher records to a PrintStream.
  */
@@ -185,12 +185,13 @@ public final class EscherDump {
                     recordName = "MsofbtUDefProp";
                     break;
                 default:
-                    if ( recordId >= (short) 0xF018 && recordId <= (short) 
0xF117 )
+                    if ( recordId >= (short) 0xF018 && recordId <= (short) 
0xF117 ) {
                         recordName = "MsofbtBLIP";
-                    else if ( ( options & (short) 0x000F ) == (short) 0x000F )
+                    } else if ( ( options & (short) 0x000F ) == (short) 0x000F 
) {
                         recordName = "UNKNOWN container";
-                    else
+                    } else {
                         recordName = "UNKNOWN ID";
+                    }
             }
 
             StringBuilder stringBuf = new StringBuilder();
@@ -308,8 +309,9 @@ public final class EscherDump {
                     out.print( " " + propertyId  );
                     if ( ( n16 & (short) 0x8000 ) == 0 )
                     {
-                        if ( ( n16 & (short) 0x4000 ) != 0 )
+                        if ( ( n16 & (short) 0x4000 ) != 0 ) {
                             out.print( ", fBlipID" );
+                        }
                         out.print( ")  " );
 
                         out.print( HexDump.toHex( n32 ) );
@@ -386,8 +388,9 @@ public final class EscherDump {
 
                 byte[] buf = new byte[nDumpSize];
                 int read = in.read( buf );
-                while ( read != -1 && read < nDumpSize )
+                while ( read != -1 && read < nDumpSize ) {
                     read += in.read( buf, read, buf.length );
+                }
                 ByteArrayInputStream bin = new ByteArrayInputStream( buf );
 
                 InputStream in1 = new InflaterInputStream( bin );
@@ -402,10 +405,11 @@ public final class EscherDump {
             boolean isContainer = ( options & (short) 0x000F ) == (short) 
0x000F;
             if ( isContainer && remainingBytes >= 0 )
             {  // Container
-                if ( recordBytesRemaining <= (int) remainingBytes )
+                if ( recordBytesRemaining <= (int) remainingBytes ) {
                     out.println( "            completed within" );
-                else
+                } else {
                     out.println( "            continued elsewhere" );
+                }
             }
             else if ( remainingBytes >= 0 )
             // -> 0x0000 ... 0x0FFF
@@ -417,9 +421,9 @@ public final class EscherDump {
                     HexDump.dump( in, out, 0, nDumpSize );
                     remainingBytes -= nDumpSize;
                 }
-            }
-            else
+            } else {
                 out.println( " >> OVERRUN <<" );
+            }
         }
 
     }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherMetafileBlip.java Fri Jun 30 
20:21:33 2017
@@ -17,19 +17,18 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.hssf.usermodel.HSSFPictureData;
-
 import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.zip.InflaterInputStream;
 import java.util.zip.DeflaterOutputStream;
+import java.util.zip.InflaterInputStream;
+
+import org.apache.poi.hssf.usermodel.HSSFPictureData;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
 
 public final class EscherMetafileBlip extends EscherBlipRecord {
     private static final POILogger log = 
POILogFactory.getLogger(EscherMetafileBlip.class);
@@ -159,7 +158,9 @@ public final class EscherMetafileBlip ex
     @Override
     public int getRecordSize() {
         int size = 8 + 50 + raw_pictureData.length;
-        if(remainingData != null) size += remainingData.length;
+        if(remainingData != null) {
+            size += remainingData.length;
+        }
         if((getOptions() ^ getSignature()) == 0x10){
             size += field_2_UID.length;
         }
@@ -310,6 +311,26 @@ public final class EscherMetafileBlip ex
     }
 
     /**
+     * Gets the filter byte - this is usually 0xFE
+     *
+     * @return the filter byte
+     */
+    public byte getFilter() {
+        return field_7_fFilter;
+    }
+    
+    /**
+     * Sets the filter byte - this is usually 0xFE
+     *
+     * @param filter the filter byte
+     */
+    public void setFilter(byte filter) {
+        field_7_fFilter = filter;
+    }
+
+    
+    
+    /**
      * Returns any remaining bytes
      *
      * @return any remaining bytes
@@ -317,48 +338,7 @@ public final class EscherMetafileBlip ex
     public byte[] getRemainingData() {
         return remainingData;
     }
-
-    // filtering is always 254 according to available docs, so no point giving 
it a setter method.
-
-    @Override
-    public String toString() {
-        String extraData = "";//HexDump.toHex(field_pictureData, 32);
-        return getClass().getName() + ":" + '\n' +
-                "  RecordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' +
-                "  Version: 0x" + HexDump.toHex( getVersion() ) + '\n' +
-                "  Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' +
-                "  UID: 0x" + HexDump.toHex( field_1_UID ) + '\n' +
-                (field_2_UID == null ? "" : ("  UID2: 0x" + HexDump.toHex( 
field_2_UID ) + '\n')) +
-                "  Uncompressed Size: " + HexDump.toHex( field_2_cb ) + '\n' +
-                "  Bounds: " + getBounds() + '\n' +
-                "  Size in EMU: " + getSizeEMU() + '\n' +
-                "  Compressed Size: " + HexDump.toHex( field_5_cbSave ) + '\n' 
+
-                "  Compression: " + HexDump.toHex( field_6_fCompression ) + 
'\n' +
-                "  Filter: " + HexDump.toHex( field_7_fFilter ) + '\n' +
-                "  Extra Data:" + '\n' + extraData +
-                (remainingData == null ? null : ("\n" +
-                 " Remaining Data: " + HexDump.toHex(remainingData, 32)));
-    }
-
-    @Override
-    public String toXml(String tab) {
-        String extraData = "";
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<UID>0x").append(HexDump.toHex( field_1_UID ) 
+ '\n' +
-                                (field_2_UID == null ? "" : ("  UID2: 0x" + 
HexDump.toHex( field_2_UID ) + '\n'))).append("</UID>\n")
-                
.append(tab).append("\t").append("<UncompressedSize>0x").append(HexDump.toHex( 
field_2_cb )).append("</UncompressedSize>\n")
-                
.append(tab).append("\t").append("<Bounds>").append(getBounds()).append("</Bounds>\n")
-                
.append(tab).append("\t").append("<SizeInEMU>").append(getSizeEMU()).append("</SizeInEMU>\n")
-                
.append(tab).append("\t").append("<CompressedSize>0x").append(HexDump.toHex( 
field_5_cbSave )).append("</CompressedSize>\n")
-                
.append(tab).append("\t").append("<Compression>0x").append(HexDump.toHex( 
field_6_fCompression )).append("</Compression>\n")
-                
.append(tab).append("\t").append("<Filter>0x").append(HexDump.toHex( 
field_7_fFilter )).append("</Filter>\n")
-                
.append(tab).append("\t").append("<ExtraData>").append(extraData).append("</ExtraData>\n")
-                
.append(tab).append("\t").append("<RemainingData>0x").append(HexDump.toHex(remainingData,
 32)).append("</RemainingData>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
-    }
-
+    
     /**
      * Return the blip signature
      *
@@ -399,12 +379,19 @@ public final class EscherMetafileBlip ex
         setCompressed(true);
     }
 
-    /**
-     * Sets the filter byte - usually this is 0xFE
-     *
-     * @param filter the filter byte
-     */
-    public void setFilter(byte filter) {
-       field_7_fFilter = filter;
+    @Override
+    protected Object[][] getAttributeMap() {
+        return new Object[][]{
+            // record, version, instance are directly fetched
+            { "UID", field_1_UID, "UID2", field_2_UID },
+            { "Uncompressed Size", field_2_cb },
+            { "Bounds", getBounds().toString() },
+            { "Size in EMU", getSizeEMU().toString() },
+            { "Compressed Size", field_5_cbSave },
+            { "Compression", field_6_fCompression },
+            { "Filter", field_7_fFilter },
+            { "Extra Data", "" },
+            { "Remaining Data", remainingData }
+        };
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherOptRecord.java Fri Jun 30 
20:21:33 2017
@@ -65,9 +65,10 @@ public class EscherOptRecord extends Abs
     @Override
     public void setVersion( short value )
     {
-        if ( value != 0x3 )
+        if ( value != 0x3 ) {
             throw new IllegalArgumentException( RECORD_DESCRIPTION
                     + " can have only '0x3' version" );
+        }
 
         super.setVersion( value );
     }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherPictBlip.java Fri Jun 30 
20:21:33 2017
@@ -17,11 +17,6 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.HexDump;
-import org.apache.poi.util.LittleEndian;
-import org.apache.poi.util.POILogFactory;
-import org.apache.poi.util.POILogger;
-
 import java.awt.Dimension;
 import java.awt.Rectangle;
 import java.io.ByteArrayInputStream;
@@ -29,6 +24,10 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.zip.InflaterInputStream;
 
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+
 public final class EscherPictBlip extends EscherBlipRecord {
     private static final POILogger log = 
POILogFactory.getLogger(EscherPictBlip.class);
 
@@ -260,39 +259,35 @@ public final class EscherPictBlip extend
         field_6_fCompression = compressed ? 0 : (byte)0xFE;
     }
 
-    // filtering is always 254 according to available docs, so no point giving 
it a setter method.
-
-    @Override
-    public String toString() {
-        String extraData = HexDump.toHex(getPicturedata(), 32);
-        return getClass().getName() + ":" + '\n' +
-                "  RecordId: 0x" + HexDump.toHex( getRecordId() ) + '\n' +
-                "  Version: 0x" + HexDump.toHex( getVersion() ) + '\n' +
-                "  Instance: 0x" + HexDump.toHex( getInstance() ) + '\n' +
-                "  UID: 0x" + HexDump.toHex( field_1_UID ) + '\n' +
-                "  Uncompressed Size: " + HexDump.toHex( field_2_cb ) + '\n' +
-                "  Bounds: " + getBounds() + '\n' +
-                "  Size in EMU: " + getSizeEMU() + '\n' +
-                "  Compressed Size: " + HexDump.toHex( field_5_cbSave ) + '\n' 
+
-                "  Compression: " + HexDump.toHex( field_6_fCompression ) + 
'\n' +
-                "  Filter: " + HexDump.toHex( field_7_fFilter ) + '\n' +
-                "  Extra Data:" + '\n' + extraData;
+    /**
+     * Gets the filter byte - this is usually 0xFE
+     *
+     * @return the filter byte
+     */
+    public byte getFilter() {
+        return field_7_fFilter;
+    }
+    
+    /**
+     * Sets the filter byte - this is usually 0xFE
+     *
+     * @param filter the filter byte
+     */
+    public void setFilter(byte filter) {
+        field_7_fFilter = filter;
     }
 
     @Override
-    public String toXml(String tab) {
-        String extraData = "";
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<UID>0x").append(HexDump.toHex( field_1_UID 
)).append("</UID>\n")
-                
.append(tab).append("\t").append("<UncompressedSize>0x").append(HexDump.toHex( 
field_2_cb )).append("</UncompressedSize>\n")
-                
.append(tab).append("\t").append("<Bounds>").append(getBounds()).append("</Bounds>\n")
-                
.append(tab).append("\t").append("<SizeInEMU>").append(getSizeEMU()).append("</SizeInEMU>\n")
-                
.append(tab).append("\t").append("<CompressedSize>0x").append(HexDump.toHex( 
field_5_cbSave )).append("</CompressedSize>\n")
-                
.append(tab).append("\t").append("<Compression>0x").append(HexDump.toHex( 
field_6_fCompression )).append("</Compression>\n")
-                
.append(tab).append("\t").append("<Filter>0x").append(HexDump.toHex( 
field_7_fFilter )).append("</Filter>\n")
-                
.append(tab).append("\t").append("<ExtraData>").append(extraData).append("</ExtraData>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
+    protected Object[][] getAttributeMap() {
+        return new Object[][]{
+            { "UID", field_1_UID },
+            { "Uncompressed Size", field_2_cb },
+            { "Bounds", getBounds().toString() },
+            { "Size in EMU", getSizeEMU().toString() },
+            { "Compressed Size", field_5_cbSave },
+            { "Compression", field_6_fCompression },
+            { "Filter", field_7_fFilter },
+            { "Extra Data", getPicturedata() },
+        };
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherProperty.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherProperty.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherProperty.java Fri Jun 30 
20:21:33 2017
@@ -107,4 +107,8 @@ public abstract class EscherProperty {
      * @return the length of the part
      */
     abstract public int serializeComplexPart( byte[] data, int pos );
-}
+
+
+    @Override
+    abstract public String toString();
+}
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherRGBProperty.java Fri Jun 30 
20:21:33 2017
@@ -68,7 +68,7 @@ public class EscherRGBProperty
         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("\" 
value=\"0x").append(HexDump.toHex(getRgbColor())).append("\"/>\n");
+                .append(isBlipId()).append("\" 
value=\"0x").append(HexDump.toHex(getRgbColor())).append("\"/>");
         return builder.toString();
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherRecord.java Fri Jun 30 20:21:33 
2017
@@ -48,11 +48,11 @@ public abstract class EscherRecord imple
 
     /**
      * Delegates to fillFields(byte[], int, EscherRecordFactory)
-     * 
+     *
      * @param data they bytes to serialize from
      * @param f the escher record factory
      * @return The number of bytes written.
-     * 
+     *
      * @see #fillFields(byte[], int, org.apache.poi.ddf.EscherRecordFactory)
      */
     protected int fillFields( byte[] data, EscherRecordFactory f )
@@ -100,7 +100,7 @@ public abstract class EscherRecord imple
 
     /**
      * Determine whether this is a container record by inspecting the option 
field.
-     * 
+     *
      * @return  true is this is a container field.
      */
     public boolean isContainerRecord() {
@@ -110,7 +110,7 @@ public abstract class EscherRecord imple
     /**
      * Note that <code>options</code> is an internal field.
      * Use {@link #setInstance(short)} ()} and {@link #setVersion(short)} ()} 
to set the actual fields.
-     * 
+     *
      * @return The options field for this record. All records have one.
      */
     @Internal
@@ -122,10 +122,10 @@ public abstract class EscherRecord imple
     /**
      * Set the options this this record. Container records should have the
      * last nibble set to 0xF.<p>
-     * 
+     *
      * Note that {@code options} is an internal field.
      * Use {@link #getInstance()} and {@link #getVersion()} to access actual 
fields.
-     * 
+     *
      * @param options the record options
      */
     @Internal
@@ -198,7 +198,7 @@ public abstract class EscherRecord imple
 
     /**
      * Sets the record id for this record.
-     * 
+     *
      * @param recordId the record id
      */
     public void setRecordId( short recordId ) {
@@ -226,9 +226,9 @@ public abstract class EscherRecord imple
 
     /**
      * Escher records may need to be clonable in the future.
-     * 
+     *
      * @return the cloned object
-     * 
+     *
      * @throws CloneNotSupportedException if the subclass hasn't implemented 
{@link Cloneable}
      */
     @Override
@@ -238,7 +238,7 @@ public abstract class EscherRecord imple
 
     /**
      * Returns the indexed child record.
-     * 
+     *
      * @param index the index of the child within the child records
      * @return the indexed child record
      */
@@ -255,20 +255,22 @@ public abstract class EscherRecord imple
      */
     public void display(PrintWriter w, int indent)
     {
-        for (int i = 0; i < indent * 4; i++) w.print(' ');
+        for (int i = 0; i < indent * 4; i++) {
+            w.print(' ');
+        }
         w.println(getRecordName());
     }
 
     /**
      * Subclasses should return the short name for this escher record.
-     * 
+     *
      * @return the short name for this escher record
      */
     public abstract String getRecordName();
 
     /**
      * Returns the instance part of the option record.
-     * 
+     *
      * @return The instance part of the record
      */
     public short getInstance()
@@ -278,7 +280,7 @@ public abstract class EscherRecord imple
 
     /**
      * Sets the instance part of record
-     * 
+     *
      * @param value instance part value
      */
     public void setInstance( short value )
@@ -288,7 +290,7 @@ public abstract class EscherRecord imple
 
     /**
      * Returns the version part of the option record.
-     * 
+     *
      * @return The version part of the option record
      */
     public short getVersion()
@@ -298,7 +300,7 @@ public abstract class EscherRecord imple
 
     /**
      * Sets the version part of record
-     * 
+     *
      * @param value version part value
      */
     public void setVersion( short value )
@@ -306,23 +308,196 @@ public abstract class EscherRecord imple
         _options = fVersion.setShortValue( _options, value );
     }
 
+    public String toXml(){
+        return toXml("");
+    }
+
     /**
-     * @param tab - each children must be a right of his parent
+     * @param tab - each children must be indented right relative to its parent
      * @return xml representation of this record
      */
-    public String toXml(String tab){
-        return tab + "<" + getClass().getSimpleName() + ">\n" +
-                tab + "\t" + "<RecordId>0x" + HexDump.toHex(_recordId) + 
"</RecordId>\n" +
-                tab + "\t" + "<Options>" + _options + "</Options>\n" +
-                tab + "</" + getClass().getSimpleName() + ">\n";
+    public final String toXml(String tab){
+        final String nl = System.getProperty( "line.separator" );
+        String clsNm = getClass().getSimpleName();
+        StringBuilder sb = new StringBuilder(1000);
+        sb.append(tab).append("<").append(clsNm)
+          .append(" recordId=\"0x").append(HexDump.toHex(getRecordId()))
+          .append("\" version=\"0x").append(HexDump.toHex(getVersion()))
+          .append("\" instance=\"0x").append(HexDump.toHex(getInstance()))
+          .append("\" options=\"0x").append(HexDump.toHex(getOptions()))
+          .append("\" recordSize=\"").append(getRecordSize());
+        Object[][] attrList = getAttributeMap();
+        if (attrList == null || attrList.length == 0) {
+            sb.append("\" />").append(nl);
+        } else {
+            sb.append("\">").append(nl);
+            String childTab = tab+"   ";
+            for (Object[] attrs : attrList) {
+                String tagName = capitalizeAndTrim((String)attrs[0]);
+                boolean hasValue = false;
+                boolean lastChildComplex = false;
+                for (int i=0; i<attrs.length; i+=2) {
+                    Object value = attrs[i+1];
+                    if (value == null) {
+                        // ignore null values
+                        continue;
+                    }
+                    if (!hasValue) {
+                        // only add tagname, when there was a value
+                        
sb.append(childTab).append("<").append(tagName).append(">");
+                    }
+                    // add names for optional attributes
+                    String optName = capitalizeAndTrim((String)attrs[i+0]);
+                    if (i>0) {
+                        sb.append(nl).append(childTab).append("  
<").append(optName).append(">");
+                    }
+                    lastChildComplex = appendValue(sb, value, true, childTab);
+                    if (i>0) {
+                        sb.append(nl).append(childTab).append("  
</").append(optName).append(">");
+                    }
+                    hasValue = true;
+                }
+                if (hasValue) {
+                    if (lastChildComplex) {
+                        sb.append(nl).append(childTab);
+                    }
+                    sb.append("</").append(tagName).append(">").append(nl);
+                }
+            }
+            sb.append(tab).append("</").append(clsNm).append(">");
+        }
+        return sb.toString();
     }
-    
-    protected String formatXmlRecordHeader(String className, String recordId, 
String version, String instance){
-        return "<" + className + " recordId=\"0x" + recordId + "\" 
version=\"0x" +
-                version + "\" instance=\"0x" + instance + "\" size=\"" + 
getRecordSize() + "\">\n";
+
+    @Override
+    public final String toString() {
+        final String nl = System.getProperty( "line.separator" );
+        StringBuilder sb = new StringBuilder(1000);
+        sb.append(getClass().getName()).append(" 
(").append(getRecordName()).append("):").append(nl)
+          .append("  RecordId: 0x").append(HexDump.toHex( getRecordId() 
)).append(nl)
+          .append("  Version: 0x").append(HexDump.toHex( getVersion() 
)).append(nl)
+          .append("  Instance: 0x").append(HexDump.toHex( getInstance() 
)).append(nl)
+          .append("  Options: 0x").append(HexDump.toHex( getOptions() 
)).append(nl)
+          .append("  Record Size: ").append( getRecordSize() );
+
+        Object[][] attrList = getAttributeMap();
+        if (attrList != null && attrList.length > 0) {
+            String childTab = "  ";
+            for (Object[] attrs : attrList) {
+                for (int i=0; i<attrs.length; i+=2) {
+                    Object value = attrs[i+1];
+                    if (value == null) {
+                        // ignore null values
+                        continue;
+                    }
+                    String name = (String)attrs[i+0];
+                    sb.append(nl).append(childTab).append(name).append(": ");
+                    appendValue(sb, value, false, childTab);
+                }
+            }
+        }
+
+        return sb.toString();
     }
     
-    public String toXml(){
-        return toXml("");
+    /**
+     * @return true, if value was a complex record, false otherwise
+     */
+    private static boolean appendValue(StringBuilder sb, Object value, boolean 
toXML, String childTab) {
+        final String nl = System.getProperty( "line.separator" );
+        boolean isComplex = false;
+        if (value instanceof String) {
+            if (toXML) {
+                escapeXML((String)value, sb);
+            } else {
+                sb.append((String)value);
+            }
+        } else if (value instanceof Byte) {
+            sb.append("0x").append(HexDump.toHex((Byte)value));
+        } else if (value instanceof Short) {
+            sb.append("0x").append(HexDump.toHex((Short)value));
+        } else if (value instanceof Integer) {
+            sb.append("0x").append(HexDump.toHex((Integer)value));
+        } else if (value instanceof byte[]) {
+            sb.append(nl).append(HexDump.toHex((byte[])value, 
32).replaceAll("(?m)^",childTab+"   "));
+        } else if (value instanceof Boolean) {
+            sb.append(((Boolean)value).booleanValue());
+        } else if (value instanceof EscherRecord) {
+            EscherRecord er = (EscherRecord)value;
+            if (toXML) {
+                sb.append(nl).append(er.toXml(childTab+"    "));
+            } else {
+                sb.append(er.toString().replaceAll("(?m)^",childTab));
+            }
+            isComplex = true;
+        } else if (value instanceof EscherProperty) {
+            EscherProperty ep = (EscherProperty)value;
+            if (toXML) {
+                sb.append(nl).append(ep.toXml(childTab+"  "));
+            } else {
+                sb.append(ep.toString().replaceAll("(?m)^",childTab));
+            }
+            isComplex = true;
+        } else {
+            throw new IllegalArgumentException("unknown attribute type 
"+value.getClass().getSimpleName());
+        }
+        return isComplex;
+    }
+
+    /**
+     * For the purpose of providing toString() and toXml() a subclass can 
either override those methods
+     * or provide a Object[][] array in the form {@code { { "Attribute Name 
(Header)", value, "optional attribute", value }, ... } }.<p>
+     *
+     * Null values won't be printed.<p>
+     *
+     * The attributes record, version, instance, options must not be returned.
+     *
+     * @return the attribute map
+     * 
+     * @since POI 3.17-beta2
+     */
+    @Internal
+    protected abstract Object[][] getAttributeMap();
+
+    private static String capitalizeAndTrim(final String str) {
+        if (str == null || str.length() == 0) {
+            return str;
+        }
+
+        StringBuilder sb = new StringBuilder(str.length());
+        boolean capitalizeNext = true;
+        for (char ch : str.toCharArray()) {
+            if (!Character.isLetterOrDigit(ch)) {
+                capitalizeNext = true;
+                continue;
+            }
+
+            if (capitalizeNext) {
+                if (!Character.isLetter(ch)) {
+                    sb.append('_');
+                } else {
+                    ch = Character.toTitleCase(ch);
+                }
+                capitalizeNext = false;
+            }
+            sb.append(ch);
+        }
+
+        return sb.toString();
+    }
+
+    private static void escapeXML(String s, StringBuilder out) {
+        if (s == null || s.isEmpty()) {
+            return;
+        }
+        for (char c : s.toCharArray()) {
+            if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
+                out.append("&#");
+                out.append((int) c);
+                out.append(';');
+            } else {
+                out.append(c);
+            }
+        }
     }
-}
+}
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherSimpleProperty.java Fri Jun 30 
20:21:33 2017
@@ -17,8 +17,8 @@
 
 package org.apache.poi.ddf;
 
-import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * A simple property is of fixed length and as a property number in addition
@@ -93,13 +93,21 @@ public class EscherSimpleProperty extend
     @Override
     public boolean equals( Object o )
     {
-        if ( this == o ) return true;
-        if ( !( o instanceof EscherSimpleProperty ) ) return false;
+        if ( this == o ) {
+            return true;
+        }
+        if ( !( o instanceof EscherSimpleProperty ) ) {
+            return false;
+        }
 
         final EscherSimpleProperty escherSimpleProperty = 
(EscherSimpleProperty) o;
 
-        if ( propertyValue != escherSimpleProperty.propertyValue ) return 
false;
-        if ( getId() != escherSimpleProperty.getId() ) return false;
+        if ( propertyValue != escherSimpleProperty.propertyValue ) {
+            return false;
+        }
+        if ( getId() != escherSimpleProperty.getId() ) {
+            return false;
+        }
 
         return true;
     }
@@ -134,7 +142,7 @@ public class EscherSimpleProperty extend
         
builder.append(tab).append("<").append(getClass().getSimpleName()).append(" 
id=\"0x").append(HexDump.toHex(getId()))
                 .append("\" name=\"").append(getName()).append("\" blipId=\"")
                 .append(isBlipId()).append("\" 
complex=\"").append(isComplex()).append("\" value=\"").append("0x")
-                .append(HexDump.toHex(propertyValue)).append("\"/>\n");
+                .append(HexDump.toHex(propertyValue)).append("\"/>");
         return builder.toString();
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java?rev=1800452&r1=1800451&r2=1800452&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherSpRecord.java Fri Jun 30 
20:21:33 2017
@@ -101,35 +101,6 @@ public class EscherSpRecord
         return "Sp";
     }
 
-
-    /**
-     * @return  the string representing this shape.
-     */
-    @Override
-    public String toString()
-    {
-        String nl = System.getProperty("line.separator");
-
-        return getClass().getName() + ":" + nl +
-                "  RecordId: 0x" + HexDump.toHex(RECORD_ID) + nl +
-                "  Version: 0x" + HexDump.toHex(getVersion()) + nl +
-                "  ShapeType: 0x" + HexDump.toHex(getShapeType()) + nl +
-                "  ShapeId: " + field_1_shapeId + nl +
-                "  Flags: " + decodeFlags(field_2_flags) + " (0x" + 
HexDump.toHex(field_2_flags) + ")" + nl;
-
-    }
-
-    @Override
-    public String toXml(String tab) {
-        StringBuilder builder = new StringBuilder();
-        
builder.append(tab).append(formatXmlRecordHeader(getClass().getSimpleName(), 
HexDump.toHex(getRecordId()), HexDump.toHex(getVersion()), 
HexDump.toHex(getInstance())))
-                
.append(tab).append("\t").append("<ShapeType>0x").append(HexDump.toHex(getShapeType())).append("</ShapeType>\n")
-                
.append(tab).append("\t").append("<ShapeId>").append(field_1_shapeId).append("</ShapeId>\n")
-                
.append(tab).append("\t").append("<Flags>").append(decodeFlags(field_2_flags) + 
" (0x" + HexDump.toHex(field_2_flags) + ")").append("</Flags>\n");
-        
builder.append(tab).append("</").append(getClass().getSimpleName()).append(">\n");
-        return builder.toString();
-    }
-
     /**
      * Converts the shape flags into a more descriptive name.
      */
@@ -242,4 +213,13 @@ public class EscherSpRecord
     {
         setInstance( value );
     }
+
+    @Override
+    protected Object[][] getAttributeMap() {
+        return new Object[][] {
+            { "ShapeType", getShapeType() },
+            { "ShapeId", field_1_shapeId },
+            { "Flags", decodeFlags(field_2_flags)+" 
(0x"+HexDump.toHex(field_2_flags)+")" }
+        };
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to