Author: josh
Date: Wed Dec 23 04:35:37 2009
New Revision: 893402

URL: http://svn.apache.org/viewvc?rev=893402&view=rev
Log:
Simplified InterfaceHdrRecord and InterfaceEndRecord (some rework after bug 
47251 / r892862).

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java
    poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
    poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
    
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/dev/BiffViewer.java Wed Dec 23 
04:35:37 2009
@@ -180,7 +180,7 @@
                        case HorizontalPageBreakRecord.sid: return new 
HorizontalPageBreakRecord(in);
                        case HyperlinkRecord.sid:      return new 
HyperlinkRecord(in);
                        case IndexRecord.sid:          return new 
IndexRecord(in);
-                       case InterfaceEndRecord.sid:   return new 
InterfaceEndRecord(in);
+                       case InterfaceEndRecord.sid:   return 
InterfaceEndRecord.create(in);
                        case InterfaceHdrRecord.sid:   return new 
InterfaceHdrRecord(in);
                        case IterationRecord.sid:      return new 
IterationRecord(in);
                        case LabelRecord.sid:          return new 
LabelRecord(in);
@@ -367,13 +367,13 @@
         * <tr><td>--noint</td><td>do not output interpretation of BIFF 
records</td></tr>
         * <tr><td>--out</td><td>send output to &lt;fileName&gt;.out</td></tr>
         * <tr><td>--rawhex</td><td>output raw hex dump of whole workbook 
stream</td></tr>
-     * <tr><td>--escher</td><td>turn on deserialization of escher records 
(default is off)</td></tr>
-     * <tr><td>--noheader</td><td>do not print record header (default is 
on)</td></tr>
+        * <tr><td>--escher</td><td>turn on deserialization of escher records 
(default is off)</td></tr>
+        * <tr><td>--noheader</td><td>do not print record header (default is 
on)</td></tr>
         * </table>
         *
         */
        public static void main(String[] args) {
-
+               // args = new String[] { "--out", "", };
                CommandArgs cmdArgs;
                try {
                        cmdArgs = CommandArgs.parse(args);
@@ -419,12 +419,12 @@
                private final Writer _hexDumpWriter;
                private final List<String> _headers;
                private final boolean _zeroAlignEachRecord;
-        private final boolean _noHeader;
+               private final boolean _noHeader;
                public BiffRecordListener(Writer hexDumpWriter, boolean 
zeroAlignEachRecord, boolean noHeader) {
                        _hexDumpWriter = hexDumpWriter;
                        _zeroAlignEachRecord = zeroAlignEachRecord;
-            _noHeader = noHeader;
-            _headers = new ArrayList<String>();
+                       _noHeader = noHeader;
+                       _headers = new ArrayList<String>();
                }
 
                public void processRecord(int globalOffset, int recordCounter, 
int sid, int dataSize,

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/InternalWorkbook.java Wed Dec 
23 04:35:37 2009
@@ -340,35 +340,35 @@
         retval.records.setRecords(records);
         List<FormatRecord> formats = retval.formats;
 
-        records.add(retval.createBOF());
-        records.add(retval.createInterfaceHdr());
-        records.add(retval.createMMS());
-        records.add(retval.createInterfaceEnd());
-        records.add(retval.createWriteAccess());
-        records.add(retval.createCodepage());
-        records.add(retval.createDSF());
-        records.add(retval.createTabId());
+        records.add(createBOF());
+        records.add(new InterfaceHdrRecord(CODEPAGE));
+        records.add(createMMS());
+        records.add(InterfaceEndRecord.instance);
+        records.add(createWriteAccess());
+        records.add(createCodepage());
+        records.add(createDSF());
+        records.add(createTabId());
         retval.records.setTabpos(records.size() - 1);
-        records.add(retval.createFnGroupCount());
+        records.add(createFnGroupCount());
         records.add(createWindowProtect());
         records.add(createProtect());
         retval.records.setProtpos(records.size() - 1);
         records.add(createPassword());
         records.add(createProtectionRev4());
-        records.add(retval.createPasswordRev4());
+        records.add(createPasswordRev4());
         retval.windowOne = createWindowOne();
         records.add(retval.windowOne);
-        records.add(retval.createBackup());
+        records.add(createBackup());
         retval.records.setBackuppos(records.size() - 1);
-        records.add(retval.createHideObj());
-        records.add(retval.createDateWindow1904());
-        records.add(retval.createPrecision());
+        records.add(createHideObj());
+        records.add(createDateWindow1904());
+        records.add(createPrecision());
         records.add(createRefreshAll());
-        records.add(retval.createBookBool());
-        records.add(retval.createFont());
-        records.add(retval.createFont());
-        records.add(retval.createFont());
-        records.add(retval.createFont());
+        records.add(createBookBool());
+        records.add(createFont());
+        records.add(createFont());
+        records.add(createFont());
+        records.add(createFont());
         retval.records.setFontpos( records.size() - 1 );   // last font record 
position
         retval.numfonts = 4;
 
@@ -1054,12 +1054,6 @@
         return retval;
     }
 
-    private static InterfaceHdrRecord createInterfaceHdr() {
-        InterfaceHdrRecord retval = new InterfaceHdrRecord();
-
-        retval.setCodepage(CODEPAGE);
-        return retval;
-    }
 
     private static MMSRecord createMMS() {
         MMSRecord retval = new MMSRecord();
@@ -1069,10 +1063,6 @@
         return retval;
     }
 
-    private static InterfaceEndRecord createInterfaceEnd() {
-        return new InterfaceEndRecord();
-    }
-
     /**
      * creates the WriteAccess record containing the logged in user's name
      */

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceEndRecord.java Wed 
Dec 23 04:35:37 2009
@@ -18,9 +18,6 @@
 package org.apache.poi.hssf.record;
 
 import org.apache.poi.util.LittleEndianOutput;
-import org.apache.poi.util.HexDump;
-import org.apache.poi.util.POILogger;
-import org.apache.poi.util.POILogFactory;
 
 /**
  * Title: Interface End Record (0x00E2)<P>
@@ -28,50 +25,39 @@
  *  (has no fields)<P>
  * REFERENCE:  PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 
1-57231-498-2)<P>
  * @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
  */
 public final class InterfaceEndRecord extends StandardRecord {
-    private static POILogger logger = 
POILogFactory.getLogger(InterfaceEndRecord.class);
 
-    public final static short sid = 0x00E2;
+    public static final short sid = 0x00E2;
+    public static final InterfaceEndRecord instance = new InterfaceEndRecord();
 
-    private byte[] _unknownData;
-
-    public InterfaceEndRecord()
-    {
+    private InterfaceEndRecord() {
+        // enforce singleton
     }
 
-    public InterfaceEndRecord(RecordInputStream in)
-    {
-        if(in.available() > 0){
-            _unknownData = in.readRemainder();
-            logger.log(POILogger.WARN, "encountered unexpected " + 
-                    _unknownData.length + " bytes in InterfaceEndRecord");
+    public static Record create(RecordInputStream in) {
+        switch (in.remaining()) {
+            case 0:
+                return instance;
+            case 2:
+                return new InterfaceHdrRecord(in);
         }
+        throw new RecordFormatException("Invalid record data size: " + 
in.remaining());
     }
 
-    public String toString()
-    {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append("[INTERFACEEND]\n");
-        buffer.append("  
unknownData=").append(HexDump.toHex(_unknownData)).append("\n");
-        buffer.append("[/INTERFACEEND]\n");
-        return buffer.toString();
+    public String toString() {
+        return "[INTERFACEEND/]\n";
     }
 
     public void serialize(LittleEndianOutput out) {
-        if(_unknownData != null) out.write(_unknownData);
+        // no instance data
     }
 
     protected int getDataSize() {
-        int size = 0;
-        if(_unknownData != null) size += _unknownData.length;
-        return size;
+        return 0;
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/InterfaceHdrRecord.java Wed 
Dec 23 04:35:37 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
@@ -15,86 +14,53 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
+import org.apache.poi.util.HexDump;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Title: Interface Header Record<P>
+ * Title: Interface Header Record (0x00E1)<P>
  * Description: Defines the beginning of Interface records (MMS)<P>
  * REFERENCE:  PG 324 Microsoft Excel 97 Developer's Kit (ISBN: 
1-57231-498-2)<P>
  * @author Andrew C. Oliver (acoliver at apache dot org)
- * @version 2.0-pre
  */
-
-public final class InterfaceHdrRecord
-    extends StandardRecord
-{
-    public final static short sid = 0xe1;
-    private short             field_1_codepage;   // = 0;
+public final class InterfaceHdrRecord extends StandardRecord {
+    public final static short sid = 0x00E1;
+    private final int _codepage;
 
     /**
      * suggested (and probably correct) default
      */
+    public final static int CODEPAGE = 0x04B0;
 
-    public final static short CODEPAGE = ( short ) 0x4b0;
-
-    public InterfaceHdrRecord()
-    {
+    public InterfaceHdrRecord(int codePage) {
+        _codepage = codePage;
     }
 
-    public InterfaceHdrRecord(RecordInputStream in)
-    {
-        field_1_codepage = in.readShort();
-    }
-
-    /**
-     * set the codepage for the file
-     *
-     * @param cp - the codepage
-     * @see #CODEPAGE
-     */
-
-    public void setCodepage(short cp)
-    {
-        field_1_codepage = cp;
-    }
-
-    /**
-     * get the codepage for the file
-     *
-     * @return the codepage
-     * @see #CODEPAGE
-     */
-
-    public short getCodepage()
-    {
-        return field_1_codepage;
+    public InterfaceHdrRecord(RecordInputStream in) {
+        _codepage = in.readShort();
     }
 
-    public String toString()
-    {
+    public String toString() {
         StringBuffer buffer = new StringBuffer();
 
         buffer.append("[INTERFACEHDR]\n");
-        buffer.append("    .codepage        = ")
-            .append(Integer.toHexString(getCodepage())).append("\n");
+        buffer.append("    .codepage = 
").append(HexDump.shortToHex(_codepage)).append("\n");
         buffer.append("[/INTERFACEHDR]\n");
         return buffer.toString();
     }
 
     public void serialize(LittleEndianOutput out) {
-        out.writeShort(getCodepage());
+        out.writeShort(_codepage);
     }
 
     protected int getDataSize() {
         return 2;
     }
 
-    public short getSid()
-    {
+    public short getSid() {
         return sid;
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java Wed Dec 23 
04:35:37 2009
@@ -20,6 +20,7 @@
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.*;
 
@@ -44,10 +45,10 @@
 
                Class<? extends Record> getRecordClass();
        }
-       private static final class ReflectionRecordCreator implements 
I_RecordCreator {
+       private static final class ReflectionConstructorRecordCreator 
implements I_RecordCreator {
 
                private final Constructor<? extends Record> _c;
-               public ReflectionRecordCreator(Constructor<? extends Record> c) 
{
+               public ReflectionConstructorRecordCreator(Constructor<? extends 
Record> c) {
                        _c = c;
                }
                public Record create(RecordInputStream in) {
@@ -68,6 +69,33 @@
                        return _c.getDeclaringClass();
                }
        }
+       /**
+        * A "create" method is used instead of the usual constructor if the 
created record might
+        * be of a different class to the declaring class.
+        */
+       private static final class ReflectionMethodRecordCreator implements 
I_RecordCreator {
+
+               private final Method _m;
+               public ReflectionMethodRecordCreator(Method m) {
+                       _m = m;
+               }
+               public Record create(RecordInputStream in) {
+                       Object[] args = { in, };
+                       try {
+                               return (Record) _m.invoke(null, args);
+                       } catch (IllegalArgumentException e) {
+                               throw new RuntimeException(e);
+                       } catch (IllegalAccessException e) {
+                               throw new RuntimeException(e);
+                       } catch (InvocationTargetException e) {
+                               throw new RecordFormatException("Unable to 
construct record instance" , e.getTargetException());
+                       }
+               }
+               @SuppressWarnings("unchecked")
+               public Class<? extends Record> getRecordClass() {
+                       return (Class<? extends Record>) _m.getDeclaringClass();
+               }
+       }
 
 
        private static final Class<?>[] CONSTRUCTOR_ARGS = { 
RecordInputStream.class, };
@@ -355,11 +383,9 @@
                                throw new RuntimeException("duplicate record 
class (" + recClass.getName() + ")");
                        }
 
-                       short sid;
-                       Constructor<? extends Record> constructor;
+                       int sid;
                        try {
                                sid = recClass.getField("sid").getShort(null);
-                               constructor = 
recClass.getConstructor(CONSTRUCTOR_ARGS);
                        } catch (Exception illegalArgumentException) {
                                throw new RecordFormatException(
                                        "Unable to determine record types");
@@ -370,12 +396,27 @@
                                throw new RuntimeException("duplicate record 
sid 0x" + Integer.toHexString(sid).toUpperCase()
                                                + " for classes (" + 
recClass.getName() + ") and (" + prevClass.getName() + ")");
                        }
-                       result.put(key, new 
ReflectionRecordCreator(constructor));
+                       result.put(key, getRecordCreator(recClass));
                }
 //             result.put(Integer.valueOf(0x0406), 
result.get(Integer.valueOf(0x06)));
                return result;
        }
 
+       private static I_RecordCreator getRecordCreator(Class<? extends Record> 
recClass) {
+               try {
+                       Constructor<? extends Record> constructor;
+                       constructor = recClass.getConstructor(CONSTRUCTOR_ARGS);
+                       return new 
ReflectionConstructorRecordCreator(constructor);
+               } catch (NoSuchMethodException e) {
+                       // fall through and look for other construction methods
+               }
+               try {
+                       Method m = recClass.getDeclaredMethod("create", 
CONSTRUCTOR_ARGS);
+                       return new ReflectionMethodRecordCreator(m);
+               } catch (NoSuchMethodException e) {
+                       throw new RuntimeException("Failed to find constructor 
or create method for (" + recClass.getName() + ").");
+               }
+       }
        /**
         * Create an array of records from an input stream
         *

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java 
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/AllRecordTests.java Wed 
Dec 23 04:35:37 2009
@@ -62,6 +62,7 @@
                result.addTestSuite(TestFontRecord.class);
                result.addTestSuite(TestFormulaRecord.class);
                result.addTestSuite(TestHyperlinkRecord.class);
+               result.addTestSuite(TestInterfaceEndRecord.class);
                result.addTestSuite(TestLabelRecord.class);
                result.addTestSuite(TestMergeCellsRecord.class);
                result.addTestSuite(TestNameRecord.class);

Modified: 
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- 
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java 
(original)
+++ 
poi/trunk/src/testcases/org/apache/poi/hssf/record/TestInterfaceEndRecord.java 
Wed Dec 23 04:35:37 2009
@@ -34,13 +34,14 @@
 public final class TestInterfaceEndRecord extends TestCase {
 
     public void testCreate() {
-        InterfaceEndRecord record = new InterfaceEndRecord();
+        InterfaceEndRecord record = InterfaceEndRecord.instance;
         assertEquals(0, record.getDataSize());
     }
 
     /**
      * Silently swallow unexpected contents in InterfaceEndRecord.
-     * Although it violates the spec, Excel silently reads such files. 
+     * Although it violates the spec, Excel silently converts this
+     * data to an {...@link InterfaceHdrRecord}.
      */
     public void testUnexpectedBytes_bug47251(){
         String hex = "" +
@@ -50,7 +51,9 @@
         byte[] data = HexRead.readFromString(hex);
         List<Record> records = RecordFactory.createRecords(new 
ByteArrayInputStream(data));
         assertEquals(3, records.size());
-        InterfaceEndRecord r = (InterfaceEndRecord)records.get(1);
-        assertEquals("[E2, 00, 02, 00, B0, 04]", HexDump.toHex(r.serialize()));
+        Record rec1 = records.get(1);
+        assertEquals(InterfaceHdrRecord.class, rec1.getClass());
+        InterfaceHdrRecord r = (InterfaceHdrRecord)rec1;
+        assertEquals("[E1, 00, 02, 00, B0, 04]", HexDump.toHex(r.serialize()));
     }
-}
\ No newline at end of file
+}

Modified: 
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java?rev=893402&r1=893401&r2=893402&view=diff
==============================================================================
--- 
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java 
(original)
+++ 
poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestSanityChecker.java 
Wed Dec 23 04:35:37 2009
@@ -39,15 +39,15 @@
  * @author Glen Stampoultzis (glens at apache.org)
  */
 public final class TestSanityChecker extends TestCase {
-
+       private static final Record INTERFACEHDR = new 
InterfaceHdrRecord(InterfaceHdrRecord.CODEPAGE);
        private static BoundSheetRecord createBoundSheetRec() {
                return new BoundSheetRecord("Sheet1");
        }
        public void testCheckRecordOrder() {
                final SanityChecker c = new SanityChecker();
-               List records = new ArrayList();
+               List<Record> records = new ArrayList<Record>();
                records.add(new BOFRecord());
-               records.add(new InterfaceHdrRecord());
+               records.add(INTERFACEHDR);
                records.add(createBoundSheetRec());
                records.add(EOFRecord.instance);
                CheckRecord[] check = {
@@ -71,15 +71,15 @@
                confirmBadRecordOrder(check, new Record[] {
                                new BOFRecord(),
                                createBoundSheetRec(),
-                               new InterfaceHdrRecord(),
+                               INTERFACEHDR,
                                EOFRecord.instance,
                });
 
                confirmBadRecordOrder(check, new Record[] {
                                new BOFRecord(),
-                               new InterfaceHdrRecord(),
+                               INTERFACEHDR,
                                createBoundSheetRec(),
-                               new InterfaceHdrRecord(),
+                               INTERFACEHDR,
                                EOFRecord.instance,
                });
 
@@ -92,19 +92,19 @@
                });
 
                confirmBadRecordOrder(check, new Record[] {
-                               new InterfaceHdrRecord(),
+                               INTERFACEHDR,
                                createBoundSheetRec(),
                                EOFRecord.instance,
                });
 
                confirmBadRecordOrder(check, new Record[] {
                                new BOFRecord(),
-                               new InterfaceHdrRecord(),
+                               INTERFACEHDR,
                                EOFRecord.instance,
                });
 
                confirmBadRecordOrder(check, new Record[] {
-                               new InterfaceHdrRecord(),
+                               INTERFACEHDR,
                                createBoundSheetRec(),
                                new BOFRecord(),
                                EOFRecord.instance,
@@ -113,7 +113,7 @@
                confirmBadRecordOrder(check, new Record[] {
                                new BOFRecord(),
                                createBoundSheetRec(),
-                               new InterfaceHdrRecord(),
+                               INTERFACEHDR,
                                EOFRecord.instance,
                });
        }



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

Reply via email to