You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2009/02/19 23:02:14 UTC

svn commit: r746018 - in /poi/trunk/src: java/org/apache/poi/ddf/EscherContainerRecord.java scratchpad/src/org/apache/poi/hslf/model/MovieShape.java testcases/org/apache/poi/ddf/TestEscherContainerRecord.java

Author: josh
Date: Thu Feb 19 22:02:14 2009
New Revision: 746018

URL: http://svn.apache.org/viewvc?rev=746018&view=rev
Log:
Fix for bug introduced in r745976.  EscherContainerRecord shouldn't hand out it's private 'child records' field.

Modified:
    poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
    poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java

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=746018&r1=746017&r2=746018&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/ddf/EscherContainerRecord.java Thu Feb 19 22:02:14 2009
@@ -34,8 +34,7 @@
  *
  * @author Glen Stampoultzis
  */
-public class EscherContainerRecord extends EscherRecord
-{
+public final class EscherContainerRecord extends EscherRecord {
     public static final short DGG_CONTAINER    = (short)0xF000;
     public static final short BSTORE_CONTAINER = (short)0xF001;
     public static final short DG_CONTAINER     = (short)0xF002;
@@ -57,7 +56,7 @@
             bytesWritten += childBytesWritten;
             offset += childBytesWritten;
             bytesRemaining -= childBytesWritten;
-            getChildRecords().add( child );
+            addChildRecord(child);
             if (offset >= data.length && bytesRemaining > 0)
             {
                 System.out.println("WARNING: " + bytesRemaining + " bytes remaining but no space left");
@@ -73,16 +72,16 @@
         LittleEndian.putShort(data, offset, getOptions());
         LittleEndian.putShort(data, offset+2, getRecordId());
         int remainingBytes = 0;
-        for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
-        {
-            EscherRecord r = (EscherRecord) iterator.next();
+        Iterator<EscherRecord> iterator = _childRecords.iterator();
+        while (iterator.hasNext()) {
+            EscherRecord r = iterator.next();
             remainingBytes += r.getRecordSize();
         }
         LittleEndian.putInt(data, offset+4, remainingBytes);
         int pos = offset+8;
-        for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
-        {
-            EscherRecord r = (EscherRecord) iterator.next();
+        iterator = _childRecords.iterator();
+        while (iterator.hasNext()) {
+            EscherRecord r = iterator.next();
             pos += r.serialize(pos, data, listener );
         }
 
@@ -90,12 +89,11 @@
         return pos - offset;
     }
 
-    public int getRecordSize()
-    {
+    public int getRecordSize() {
         int childRecordsSize = 0;
-        for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
-        {
-            EscherRecord r = (EscherRecord) iterator.next();
+        Iterator<EscherRecord> iterator = _childRecords.iterator();
+        while (iterator.hasNext()) {
+            EscherRecord r = iterator.next();
             childRecordsSize += r.getRecordSize();
         }
         return 8 + childRecordsSize;
@@ -106,46 +104,51 @@
      *  given recordId?
      */
     public boolean hasChildOfType(short recordId) {
-        for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
-        {
-            EscherRecord r = (EscherRecord) iterator.next();
+        Iterator<EscherRecord> iterator = _childRecords.iterator();
+        while (iterator.hasNext()) {
+            EscherRecord r = iterator.next();
             if(r.getRecordId() == recordId) {
                 return true;
             }
         }
         return false;
     }
-
+    
     /**
-     * Returns a list of all the child (escher) records
-     *  of the container.
+     * @return a copy of the list of all the child records of the container.
      */
     public List<EscherRecord> getChildRecords() {
-        return _childRecords;
+        return new ArrayList<EscherRecord>(_childRecords);
     }
-    
+    /**
+     * replaces the internal child list with the contents of the supplied <tt>childRecords</tt>
+     */
+    public void setChildRecords(List<EscherRecord> childRecords) {
+    	if (childRecords == _childRecords) {
+    		throw new IllegalStateException("Child records private data member has escaped");
+    	}
+        _childRecords.clear();
+        _childRecords.addAll(childRecords);
+    }
+
+   
     /**
      * Returns all of our children which are also
      *  EscherContainers (may be 0, 1, or vary rarely
      *   2 or 3)
      */
-    public List getChildContainers() {
-        List containers = new ArrayList();
-        for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
-        {
-            EscherRecord r = (EscherRecord) iterator.next();
+    public List<EscherContainerRecord> getChildContainers() {
+        List<EscherContainerRecord> containers = new ArrayList<EscherContainerRecord>();
+        Iterator<EscherRecord> iterator = _childRecords.iterator();
+        while (iterator.hasNext()) {
+            EscherRecord r = iterator.next();
             if(r instanceof EscherContainerRecord) {
-            	containers.add(r);
+            	containers.add((EscherContainerRecord) r);
             }
         }
         return containers;
     }
 
-    public void setChildRecords(List<EscherRecord> childRecords) {
-        _childRecords.clear();
-        _childRecords.addAll(childRecords);
-    }
-
     public String getRecordName() {
         switch (getRecordId()) {
             case DGG_CONTAINER:
@@ -165,13 +168,12 @@
         }
     }
 
-    public void display( PrintWriter w, int indent )
-    {
-        super.display( w, indent );
-        for (Iterator iterator = _childRecords.iterator(); iterator.hasNext();)
+    public void display(PrintWriter w, int indent) {
+        super.display(w, indent);
+        for (Iterator<EscherRecord> iterator = _childRecords.iterator(); iterator.hasNext();)
         {
-            EscherRecord escherRecord = (EscherRecord) iterator.next();
-            escherRecord.display( w, indent + 1 );
+            EscherRecord escherRecord = iterator.next();
+            escherRecord.display(w, indent + 1);
         }
     }
 
@@ -188,16 +190,15 @@
         String nl = System.getProperty( "line.separator" );
 
         StringBuffer children = new StringBuffer();
-        if ( getChildRecords().size() > 0 )
-        {
+        if (_childRecords.size() > 0) {
             children.append( "  children: " + nl );
             
             int count = 0;
-            for ( Iterator iterator = getChildRecords().iterator(); iterator.hasNext(); )
+            for ( Iterator<EscherRecord> iterator = _childRecords.iterator(); iterator.hasNext(); )
             {
             	String newIndent = indent + "   ";
             	
-                EscherRecord record = (EscherRecord) iterator.next();
+                EscherRecord record = iterator.next();
                 children.append(newIndent + "Child " + count + ":" + nl);
                 
                 if(record instanceof EscherContainerRecord) {
@@ -215,18 +216,17 @@
             indent + "  isContainer: " + isContainerRecord() + nl +
             indent + "  options: 0x" + HexDump.toHex( getOptions() ) + nl +
             indent + "  recordId: 0x" + HexDump.toHex( getRecordId() ) + nl +
-            indent + "  numchildren: " + getChildRecords().size() + nl +
+            indent + "  numchildren: " + _childRecords.size() + nl +
             indent + children.toString();
 
     }
 
-    public EscherSpRecord getChildById( short recordId )
-    {
-        for ( Iterator iterator = _childRecords.iterator(); iterator.hasNext(); )
-        {
-            EscherRecord escherRecord = (EscherRecord) iterator.next();
-            if (escherRecord.getRecordId() == recordId)
-                return (EscherSpRecord) escherRecord;
+    public EscherSpRecord getChildById(short recordId) {
+        Iterator<EscherRecord> iterator = _childRecords.iterator();
+        while (iterator.hasNext()) {
+            EscherRecord r = iterator.next();
+            if (r.getRecordId() == recordId)
+                return (EscherSpRecord) r;
         }
         return null;
     }
@@ -236,15 +236,15 @@
      *
      * @param out - list to store found records
      */
-    public void getRecordsById(short recordId, List out){
-        for(Iterator it = _childRecords.iterator(); it.hasNext();) {
-            Object er = it.next();
-            EscherRecord r = (EscherRecord)er;
+    public void getRecordsById(short recordId, List<EscherRecord> out){
+        Iterator<EscherRecord> iterator = _childRecords.iterator();
+        while (iterator.hasNext()) {
+            EscherRecord r = iterator.next();
             if(r instanceof EscherContainerRecord) {
                 EscherContainerRecord c = (EscherContainerRecord)r;
                 c.getRecordsById(recordId, out );
             } else if (r.getRecordId() == recordId){
-                out.add(er);
+                out.add(r);
             }
         }
     }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java?rev=746018&r1=746017&r2=746018&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/MovieShape.java Thu Feb 19 22:02:14 2009
@@ -83,7 +83,7 @@
 
         EscherClientDataRecord cldata = new EscherClientDataRecord();
         cldata.setOptions((short)0xF);
-        _escherContainer.getChildRecords().add(cldata);
+        _escherContainer.addChildRecord(cldata);
 
         OEShapeAtom oe = new OEShapeAtom();
         InteractiveInfo info = new InteractiveInfo();

Modified: poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java?rev=746018&r1=746017&r2=746018&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ddf/TestEscherContainerRecord.java Thu Feb 19 22:02:14 2009
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -20,14 +19,17 @@
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.util.List;
 
 import junit.framework.TestCase;
 import org.apache.poi.util.HexRead;
 import org.apache.poi.util.HexDump;
 import org.apache.poi.util.IOUtils;
 
-public class TestEscherContainerRecord extends TestCase
-{
+/**
+ * Tests for {@link EscherContainerRecord}
+ */
+public final class TestEscherContainerRecord extends TestCase {
 	private String ESCHER_DATA_PATH;
 	
 	protected void setUp() {
@@ -129,17 +131,18 @@
                    "  properties:" + nl;
         assertEquals( expected, r.toString() );
     }
+    
+    private static final class DummyEscherRecord extends EscherRecord {
+    	public DummyEscherRecord() { }
+        public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ) { return 0; }
+        public int serialize( int offset, byte[] data, EscherSerializationListener listener ) { return 0; }
+        public int getRecordSize() { return 10; }
+        public String getRecordName() { return ""; }
+    }
 
     public void testGetRecordSize() {
         EscherContainerRecord r = new EscherContainerRecord();
-        r.addChildRecord(new EscherRecord()
-        {
-            public int fillFields( byte[] data, int offset, EscherRecordFactory recordFactory ) { return 0; }
-            public int serialize( int offset, byte[] data, EscherSerializationListener listener ) { return 0; }
-            public int getRecordSize() { return 10; }
-            public String getRecordName() { return ""; }
-        } );
-
+        r.addChildRecord(new DummyEscherRecord());
         assertEquals(18, r.getRecordSize());
     }
 
@@ -158,4 +161,36 @@
     	EscherContainerRecord record = new EscherContainerRecord();
     	record.fillFields(data, 0, new DefaultEscherRecordFactory());
     }
+    
+    /**
+     * Ensure {@link EscherContainerRecord} doesn't spill its guts everywhere
+     */
+    public void testChildren() {
+    	EscherContainerRecord ecr = new EscherContainerRecord();
+    	List<EscherRecord> children0 = ecr.getChildRecords();
+    	assertEquals(0, children0.size());
+
+    	EscherRecord chA = new DummyEscherRecord();
+    	EscherRecord chB = new DummyEscherRecord();
+    	EscherRecord chC = new DummyEscherRecord();
+    	
+    	ecr.addChildRecord(chA);
+    	ecr.addChildRecord(chB);
+    	children0.add(chC);
+    	
+    	List<EscherRecord> children1 = ecr.getChildRecords();
+    	assertTrue(children0 !=  children1);
+    	assertEquals(2, children1.size());
+    	assertEquals(chA, children1.get(0));
+    	assertEquals(chB, children1.get(1));
+    	
+    	assertEquals(1, children0.size()); // first copy unchanged
+    	
+    	ecr.setChildRecords(children0);
+    	ecr.addChildRecord(chA);
+    	List<EscherRecord> children2 = ecr.getChildRecords();
+    	assertEquals(2, children2.size());
+    	assertEquals(chC, children2.get(0));
+    	assertEquals(chA, children2.get(1));
+	}
 }



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