poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r682508 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/eventmodel/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/usermodel/ testcases/org/apache/poi/hssf/eventmodel/ testcases/org/apache/poi/hssf/mode...
Date Mon, 04 Aug 2008 21:08:11 GMT
Author: josh
Date: Mon Aug  4 14:08:11 2008
New Revision: 682508

URL: http://svn.apache.org/viewvc?rev=682508&view=rev
Log:
Patch 44894 - refactoring duplicate logic from EventRecordFactory to RecordFactory

Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java
    poi/trunk/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java
    poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
    poi/trunk/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java
    poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Mon Aug  4 14:08:11 2008
@@ -37,6 +37,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.1.1-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">44894 - refactor duplicate logic from EventRecordFactory to RecordFactory</action>
            <action dev="POI-DEVELOPERS" type="add">Support for Headers / Footers in HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">44953 - Extensive fixes for data validation</action>
            <action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Mon Aug  4 14:08:11 2008
@@ -34,6 +34,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.1.1-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">44894 - refactor duplicate logic from EventRecordFactory to RecordFactory</action>
            <action dev="POI-DEVELOPERS" type="add">Support for Headers / Footers in HSLF</action>
            <action dev="POI-DEVELOPERS" type="fix">44953 - Extensive fixes for data validation</action>
            <action dev="POI-DEVELOPERS" type="fix">45519 - Fixed to keep datavalidation records together</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/eventmodel/EventRecordFactory.java Mon Aug  4 14:08:11 2008
@@ -18,241 +18,60 @@
 package org.apache.poi.hssf.eventmodel;
 
 import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.poi.hssf.record.BOFRecord;
-import org.apache.poi.hssf.record.BackupRecord;
-import org.apache.poi.hssf.record.BlankRecord;
-import org.apache.poi.hssf.record.BookBoolRecord;
-import org.apache.poi.hssf.record.BoolErrRecord;
-import org.apache.poi.hssf.record.BottomMarginRecord;
-import org.apache.poi.hssf.record.BoundSheetRecord;
-import org.apache.poi.hssf.record.CalcCountRecord;
-import org.apache.poi.hssf.record.CalcModeRecord;
-import org.apache.poi.hssf.record.CodepageRecord;
-import org.apache.poi.hssf.record.ColumnInfoRecord;
-import org.apache.poi.hssf.record.ContinueRecord;
-import org.apache.poi.hssf.record.CountryRecord;
-import org.apache.poi.hssf.record.DBCellRecord;
-import org.apache.poi.hssf.record.DSFRecord;
-import org.apache.poi.hssf.record.DateWindow1904Record;
-import org.apache.poi.hssf.record.DefaultColWidthRecord;
-import org.apache.poi.hssf.record.DefaultRowHeightRecord;
-import org.apache.poi.hssf.record.DeltaRecord;
-import org.apache.poi.hssf.record.DimensionsRecord;
-import org.apache.poi.hssf.record.EOFRecord;
-import org.apache.poi.hssf.record.ExtSSTRecord;
-import org.apache.poi.hssf.record.ExtendedFormatRecord;
-import org.apache.poi.hssf.record.ExternSheetRecord;
-import org.apache.poi.hssf.record.FnGroupCountRecord;
-import org.apache.poi.hssf.record.FontRecord;
-import org.apache.poi.hssf.record.FooterRecord;
-import org.apache.poi.hssf.record.FormatRecord;
-import org.apache.poi.hssf.record.GridsetRecord;
-import org.apache.poi.hssf.record.GutsRecord;
-import org.apache.poi.hssf.record.HCenterRecord;
-import org.apache.poi.hssf.record.HeaderRecord;
-import org.apache.poi.hssf.record.HideObjRecord;
-import org.apache.poi.hssf.record.IndexRecord;
-import org.apache.poi.hssf.record.InterfaceEndRecord;
-import org.apache.poi.hssf.record.InterfaceHdrRecord;
-import org.apache.poi.hssf.record.IterationRecord;
-import org.apache.poi.hssf.record.LabelRecord;
-import org.apache.poi.hssf.record.LabelSSTRecord;
-import org.apache.poi.hssf.record.LeftMarginRecord;
-import org.apache.poi.hssf.record.MMSRecord;
-import org.apache.poi.hssf.record.MergeCellsRecord;
-import org.apache.poi.hssf.record.MulBlankRecord;
-import org.apache.poi.hssf.record.MulRKRecord;
-import org.apache.poi.hssf.record.NameRecord;
-import org.apache.poi.hssf.record.NumberRecord;
-import org.apache.poi.hssf.record.PaneRecord;
-import org.apache.poi.hssf.record.PaletteRecord;
-import org.apache.poi.hssf.record.PasswordRecord;
-import org.apache.poi.hssf.record.PasswordRev4Record;
-import org.apache.poi.hssf.record.PrecisionRecord;
-import org.apache.poi.hssf.record.PrintGridlinesRecord;
-import org.apache.poi.hssf.record.PrintHeadersRecord;
-import org.apache.poi.hssf.record.PrintSetupRecord;
-import org.apache.poi.hssf.record.ProtectRecord;
-import org.apache.poi.hssf.record.ProtectionRev4Record;
-import org.apache.poi.hssf.record.RKRecord;
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.RecordFormatException;
-import org.apache.poi.hssf.record.RecordInputStream;
-import org.apache.poi.hssf.record.RefModeRecord;
-import org.apache.poi.hssf.record.RefreshAllRecord;
-import org.apache.poi.hssf.record.RightMarginRecord;
-import org.apache.poi.hssf.record.RowRecord;
-import org.apache.poi.hssf.record.SSTRecord;
-import org.apache.poi.hssf.record.SaveRecalcRecord;
-import org.apache.poi.hssf.record.SelectionRecord;
-import org.apache.poi.hssf.record.SharedFormulaRecord;
-import org.apache.poi.hssf.record.StringRecord;
-import org.apache.poi.hssf.record.StyleRecord;
-import org.apache.poi.hssf.record.TabIdRecord;
-import org.apache.poi.hssf.record.TableRecord;
-import org.apache.poi.hssf.record.TopMarginRecord;
-import org.apache.poi.hssf.record.UnknownRecord;
-import org.apache.poi.hssf.record.UseSelFSRecord;
-import org.apache.poi.hssf.record.VCenterRecord;
-import org.apache.poi.hssf.record.WSBoolRecord;
-import org.apache.poi.hssf.record.WindowOneRecord;
-import org.apache.poi.hssf.record.WindowProtectRecord;
-import org.apache.poi.hssf.record.WindowTwoRecord;
-import org.apache.poi.hssf.record.WriteAccessRecord;
-import org.apache.poi.hssf.record.WriteProtectRecord;
-import org.apache.poi.hssf.record.FilePassRecord;
-import org.apache.poi.hssf.record.NoteRecord;
+import java.util.Arrays;
 
+import org.apache.poi.hssf.record.*;
 
 /**
  * Event-based record factory.  As opposed to RecordFactory
- * this refactored version throws record events as it comes
- * accross the records.  I throws the "lazily" one record behind
- * to ensure that ContinueRecords are processed first.
+ * this version sends {@link ERFListener#processRecord(Record) } messages to 
+ * the supplied listener.  Record notifications are sent one record behind
+ * to ensure that {@link ContinueRecord}s are processed first.
  * 
  * @author Andrew C. Oliver (acoliver@apache.org) - probably to blame for the bugs (so yank his chain on the list)
  * @author Marc Johnson (mjohnson at apache dot org) - methods taken from RecordFactory
  * @author Glen Stampoultzis (glens at apache.org) - methods taken from RecordFactory
  * @author Csaba Nagy (ncsaba at yahoo dot com)
  */
-public class EventRecordFactory
-{
-    
-    /**
-     * contains the classes for all the records we want to parse.
-     */
-    private static final Class[] records;
-
-    static {
-            records = new Class[]
-            {
-                BOFRecord.class, InterfaceHdrRecord.class, MMSRecord.class,
-                InterfaceEndRecord.class, WriteAccessRecord.class,
-                CodepageRecord.class, DSFRecord.class, TabIdRecord.class,
-                FnGroupCountRecord.class, WindowProtectRecord.class,
-                ProtectRecord.class, PasswordRecord.class, ProtectionRev4Record.class,
-                PasswordRev4Record.class, WindowOneRecord.class, BackupRecord.class,
-                HideObjRecord.class, DateWindow1904Record.class,
-                PrecisionRecord.class, RefreshAllRecord.class, BookBoolRecord.class,
-                FontRecord.class, FormatRecord.class, ExtendedFormatRecord.class,
-                StyleRecord.class, UseSelFSRecord.class, BoundSheetRecord.class,
-                CountryRecord.class, SSTRecord.class, ExtSSTRecord.class,
-                EOFRecord.class, IndexRecord.class, CalcModeRecord.class,
-                CalcCountRecord.class, RefModeRecord.class, IterationRecord.class,
-                DeltaRecord.class, SaveRecalcRecord.class, PrintHeadersRecord.class,
-                PrintGridlinesRecord.class, GridsetRecord.class, GutsRecord.class,
-                DefaultRowHeightRecord.class, WSBoolRecord.class, HeaderRecord.class,
-                FooterRecord.class, HCenterRecord.class, VCenterRecord.class,
-                PrintSetupRecord.class, DefaultColWidthRecord.class,
-                DimensionsRecord.class, RowRecord.class, LabelSSTRecord.class,
-                RKRecord.class, NumberRecord.class, DBCellRecord.class,
-                WindowTwoRecord.class, SelectionRecord.class, ContinueRecord.class,
-                LabelRecord.class, BlankRecord.class, ColumnInfoRecord.class,
-                MulRKRecord.class, MulBlankRecord.class, MergeCellsRecord.class,
-                BoolErrRecord.class, ExternSheetRecord.class, NameRecord.class,
-                LeftMarginRecord.class, RightMarginRecord.class,
-                TopMarginRecord.class, BottomMarginRecord.class,
-                PaletteRecord.class, StringRecord.class, SharedFormulaRecord.class, 
-                WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class,
-                NoteRecord.class, TableRecord.class
-            };
-       
-    }
-    
-    /**
-     * cache of the recordsToMap();
-     */
-    private static Map           recordsMap  = recordsToMap(records);
-
-    /**
-     * cache of the return of getAllKnownSids so that we don't have to
-     * expensively get them every time.
-     */
-    private static short[] sidscache;
+public final class EventRecordFactory {
 
-    /**
-     * List of the listners that are registred.  should all be ERFListener
-     */    
-    private List listeners;
-
-    /**
-     * instance is abortable or not
-     */
-    private boolean abortable;
-    
-    /**
-     * Construct an abortable EventRecordFactory.  
-     * The same as calling new EventRecordFactory(true)
-     * @see #EventRecordFactory(boolean)
-     */
-    public EventRecordFactory() {
-        this(true);                  
-    }
-    
-    /**
-     * Create an EventRecordFactory
-     * @param abortable specifies whether the return from the listener 
-     * handler functions are obeyed.  False means they are ignored. True
-     * means the event loop exits on error.
-     */
-    public EventRecordFactory(boolean abortable) {
-        this.abortable = abortable;
-        listeners = new ArrayList(recordsMap.size());    
-        
-        if (sidscache == null) {
-         sidscache = getAllKnownRecordSIDs();   
-        }
+    private final ERFListener _listener;
+	private final short[] _sids;
 
-    }
-    
     /**
-     * Register a listener for records.  These can be for all records 
-     * or just a subset.
-     * 
+     *
      * @param sids an array of Record.sid values identifying the records
      * the listener will work with.  Alternatively if this is "null" then 
-     * all records are passed.
+     * all records are passed. For all 'known' record types use {@link RecordFactory#getAllKnownRecordSIDs()}
      */
-    public void registerListener(ERFListener listener, short[] sids) {
-      if (sids == null)
-        sids = sidscache;
-      ERFListener wrapped = new ListenerWrapper(listener, sids, abortable);    
-      listeners.add(wrapped);
-    }
-    
-    /**
-     * used for unit tests to test the registration of record listeners.
-     * @return Iterator of ERFListeners
-     */
-    protected Iterator listeners() {
-        return listeners.iterator();
-    }
+    public EventRecordFactory(ERFListener listener, short[] sids) {
+        _listener = listener;
+        if (sids == null) {
+        	_sids = null;
+        } else {
+            _sids = (short[]) sids.clone();
+            Arrays.sort(_sids); // for faster binary search
+        }
+    }
+	private boolean isSidIncluded(short sid) {
+		if (_sids == null) {
+			return true;
+		}
+		return Arrays.binarySearch(_sids, sid) >= 0;
+	}   
+
 
     /**
      * sends the record event to all registered listeners.
      * @param record the record to be thrown.
-     * @return boolean abort.  If exitability is turned on this aborts
-     * out of the event loop should any listener specify to do so.
+     * @return <code>false</code> to abort.  This aborts
+     * out of the event loop should the listener return false
      */
-    private boolean throwRecordEvent(Record record)
-    {
-        boolean result = true;
-        Iterator i = listeners.iterator();
-        
-        while (i.hasNext()) {
-            result = ((ERFListener) i.next()).processRecord(record);  
-            if (abortable == true && result == false) {
-                break;   
-            }
-        }
-        return result;
+    private boolean processRecord(Record record) {
+    	if (!isSidIncluded(record.getSid())) {
+    		return true;
+    	}
+    	return _listener.processRecord(record);
     }
 
     /**
@@ -264,220 +83,39 @@
      * @exception RecordFormatException on error processing the
      *            InputStream
      */
-    public void processRecords(InputStream in)
-        throws RecordFormatException
-    {
-        Record    last_record = null;
+    public void processRecords(InputStream in) throws RecordFormatException {
+        Record last_record = null;
 
         RecordInputStream recStream = new RecordInputStream(in);
 
         while (recStream.hasNextRecord()) {
-          recStream.nextRecord();
-          Record[] recs = createRecord(recStream);   // handle MulRK records
-                    if (recs.length > 1)
-                    {
-                        for (int k = 0; k < recs.length; k++)
-                        {
-                            if ( last_record != null ) {
-                                if (throwRecordEvent(last_record) == false && abortable == true) {
-                                 last_record = null;
-                                 break;   
-                                }
-                            }
-                            last_record =
-                                recs[ k ];                // do to keep the algorythm homogenous...you can't
-                        }                                 // actually continue a number record anyhow.
+            recStream.nextRecord();
+            Record[] recs = RecordFactory.createRecord(recStream);   // handle MulRK records
+            if (recs.length > 1) {
+                for (int k = 0; k < recs.length; k++) {
+                    if ( last_record != null ) {
+                        if (!processRecord(last_record)) {
+                            return;   
+                        }
                     }
-                    else
-                    {
-                        Record record = recs[ 0 ];
-
-                        if (record != null)
-                        {
-                                if (last_record != null) {
-                                    if (throwRecordEvent(last_record) == false && abortable == true) {
-                                        last_record = null;
-                                        break;   
-                                    }
-                                }
-                                
-                                last_record = record;
-                            }
+                    last_record = recs[ k ]; // do to keep the algorithm homogeneous...you can't
+                }                            // actually continue a number record anyhow.
+            } else {
+                Record record = recs[ 0 ];
+
+                if (record != null) {
+                    if (last_record != null) {
+                        if (!processRecord(last_record)) {
+                            return;   
                         }
                     }
-
-            
-            if (last_record != null) {
-               throwRecordEvent(last_record);               
-            }
-        }
-
-    /**
-     * create a record, if there are MUL records than multiple records
-     * are returned digested into the non-mul form.
-     */
-    public static Record [] createRecord(RecordInputStream in)
-    {
-        Record   retval     = null;
-        Record[] realretval = null;
-
-        try
-        {
-            Constructor constructor =
-                ( Constructor ) recordsMap.get(new Short(in.getSid()));
-
-            if (constructor != null)
-            {
-                retval = ( Record ) constructor.newInstance(new Object[]
-                {
-                    in
-                });
-            }
-            else
-            {
-                retval = new UnknownRecord(in);
-            }
-        }
-        catch (Exception introspectionException)
-        {
-            throw new RecordFormatException("Unable to construct record instance" , introspectionException);
-        }
-        if (retval instanceof RKRecord)
-        {
-            RKRecord     rk  = ( RKRecord ) retval;
-            NumberRecord num = new NumberRecord();
-
-            num.setColumn(rk.getColumn());
-            num.setRow(rk.getRow());
-            num.setXFIndex(rk.getXFIndex());
-            num.setValue(rk.getRKNumber());
-            retval = num;
-        }
-        else if (retval instanceof DBCellRecord)
-        {
-            retval = null;
-        }
-        else if (retval instanceof MulRKRecord)
-        {
-            MulRKRecord mrk = ( MulRKRecord ) retval;
-
-            realretval = new Record[ mrk.getNumColumns() ];
-            for (int k = 0; k < mrk.getNumColumns(); k++)
-            {
-                NumberRecord nr = new NumberRecord();
-
-                nr.setColumn(( short ) (k + mrk.getFirstColumn()));
-                nr.setRow(mrk.getRow());
-                nr.setXFIndex(mrk.getXFAt(k));
-                nr.setValue(mrk.getRKNumberAt(k));
-                realretval[ k ] = nr;
-            }
-        }
-        else if (retval instanceof MulBlankRecord)
-        {
-            MulBlankRecord mb = ( MulBlankRecord ) retval;
-
-            realretval = new Record[ mb.getNumColumns() ];
-            for (int k = 0; k < mb.getNumColumns(); k++)
-            {
-                BlankRecord br = new BlankRecord();
-
-                br.setColumn(( short ) (k + mb.getFirstColumn()));
-                br.setRow(mb.getRow());
-                br.setXFIndex(mb.getXFAt(k));
-                realretval[ k ] = br;
-            }
-        }
-        if (realretval == null)
-        {
-            realretval      = new Record[ 1 ];
-            realretval[ 0 ] = retval;
-        }
-        return realretval;
-    }
-
-    /**
-     * @return an array of all the SIDS for all known records
-     */
-    public static short [] getAllKnownRecordSIDs()
-    {
-        short[] results = new short[ recordsMap.size() ];
-        int     i       = 0;
-
-        for (Iterator iterator = recordsMap.keySet().iterator();
-                iterator.hasNext(); )
-        {
-            Short sid = ( Short ) iterator.next();
-
-            results[ i++ ] = sid.shortValue();
-        }
-        return results;
-    }
-
-    /**
-     * gets the record constructors and sticks them in the map by SID
-     * @return map of SIDs to short,short,byte[] constructors for Record classes
-     * most of org.apache.poi.hssf.record.*
-     */
-    private static Map recordsToMap(Class [] records)
-    {
-        Map         result = new HashMap();
-        Constructor constructor;
-
-        for (int i = 0; i < records.length; i++)
-        {
-            Class record = null;
-            short sid    = 0;
-
-            record = records[ i ];
-            try
-            {
-                sid         = record.getField("sid").getShort(null);
-                constructor = record.getConstructor(new Class[]
-                {
-                    RecordInputStream.class
-                });
-            }
-            catch (Exception illegalArgumentException)
-            {
-                throw new RecordFormatException(
-                    "Unable to determine record types");
+                     last_record = record;
+                }
             }
-            result.put(new Short(sid), constructor);
         }
-        return result;
-    }
-
-}
-
-/**
- * ListenerWrapper just wraps an ERFListener and adds support for throwing
- * the event to multiple SIDs
- */
-class ListenerWrapper implements ERFListener {
-       private ERFListener listener;
-       private short[] sids;
-       private boolean abortable;
-
-    ListenerWrapper(ERFListener listener, short[] sids, boolean abortable) {
-        this.listener = listener;
-        this.sids = sids;   
-        this.abortable = abortable;
-    }       
-    
-
-    public boolean processRecord(Record rec)
-    {
-        boolean result = true;
-        for (int k = 0; k < sids.length; k++) {
-            if (sids[k] == rec.getSid()) {
-                result = listener.processRecord(rec);
             
-                if (abortable == true && result == false) {
-                    break;   
-                }
-            }
+        if (last_record != null) {
+        	processRecord(last_record);               
         }
-        return result;
-    }   
-}
+    }
+}
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/eventmodel/ModelFactory.java Mon Aug  4 14:08:11 2008
@@ -65,8 +65,7 @@
      * Start processing the Workbook stream into Model events.
      */
     public void run(InputStream stream) {
-        EventRecordFactory factory = new EventRecordFactory(true);
-        factory.registerListener(this,null);
+        EventRecordFactory factory = new EventRecordFactory(this,null);
         lastEOF = true;
         factory.processRecords(stream);
     }

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=682508&r1=682507&r2=682508&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 Mon Aug  4 14:08:11 2008
@@ -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,201 +14,186 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.hssf.record;
 
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
-import java.util.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Title:  Record Factory<P>
  * Description:  Takes a stream and outputs an array of Record objects.<P>
  *
- * @deprecated use {@link org.apache.poi.hssf.eventmodel.EventRecordFactory} instead
  * @see org.apache.poi.hssf.eventmodel.EventRecordFactory
  * @author Andrew C. Oliver (acoliver at apache dot org)
  * @author Marc Johnson (mjohnson at apache dot org)
  * @author Glen Stampoultzis (glens at apache.org)
  * @author Csaba Nagy (ncsaba at yahoo dot com)
  */
+public final class RecordFactory {
+    private static final int NUM_RECORDS = 512;
 
-public class RecordFactory
-{
-    private static int           NUM_RECORDS = 10000;
-    private static final Class[] records;
-
-    static {
-            records = new Class[]
-            {
-                BOFRecord.class, InterfaceHdrRecord.class, MMSRecord.class,
-                InterfaceEndRecord.class, WriteAccessRecord.class,
-                CodepageRecord.class, DSFRecord.class, TabIdRecord.class,
-                FnGroupCountRecord.class, WindowProtectRecord.class,
-                ProtectRecord.class, PasswordRecord.class, ProtectionRev4Record.class,
-                PasswordRev4Record.class, WindowOneRecord.class, BackupRecord.class,
-                HideObjRecord.class, DateWindow1904Record.class,
-                PrecisionRecord.class, RefreshAllRecord.class, BookBoolRecord.class,
-                FontRecord.class, FormatRecord.class, ExtendedFormatRecord.class,
-                StyleRecord.class, UseSelFSRecord.class, BoundSheetRecord.class,
-                CountryRecord.class, SSTRecord.class, ExtSSTRecord.class,
-                EOFRecord.class, IndexRecord.class, CalcModeRecord.class,
-                CalcCountRecord.class, RefModeRecord.class, IterationRecord.class,
-                DeltaRecord.class, SaveRecalcRecord.class, PrintHeadersRecord.class,
-                PrintGridlinesRecord.class, GridsetRecord.class, GutsRecord.class,
-                DefaultRowHeightRecord.class, WSBoolRecord.class, HeaderRecord.class,
-                FooterRecord.class, HCenterRecord.class, VCenterRecord.class,
-                PrintSetupRecord.class, DefaultColWidthRecord.class,
-                DimensionsRecord.class, RowRecord.class, LabelSSTRecord.class,
-                RKRecord.class, NumberRecord.class, DBCellRecord.class,
-                WindowTwoRecord.class, SelectionRecord.class, ContinueRecord.class,
-                LabelRecord.class, BlankRecord.class, ColumnInfoRecord.class,
-                MulRKRecord.class, MulBlankRecord.class, MergeCellsRecord.class,
-                FormulaRecord.class, BoolErrRecord.class, ExternSheetRecord.class,
-                NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class,
-                TopMarginRecord.class, BottomMarginRecord.class,
-                DrawingRecord.class, DrawingGroupRecord.class, DrawingSelectionRecord.class,
-                ObjRecord.class, TextObjectRecord.class,
-                PaletteRecord.class, StringRecord.class, RecalcIdRecord.class, SharedFormulaRecord.class,
-                HorizontalPageBreakRecord.class, VerticalPageBreakRecord.class, 
-                WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class,
-                NoteRecord.class, ObjectProtectRecord.class, ScenarioProtectRecord.class, 
-                FileSharingRecord.class, ChartTitleFormatRecord.class,
-                DVRecord.class, DVALRecord.class, UncalcedRecord.class,
-                ChartRecord.class, LegendRecord.class, ChartTitleFormatRecord.class, 
-                SeriesRecord.class, SeriesTextRecord.class,
-                HyperlinkRecord.class,
-                ExternalNameRecord.class, // TODO - same changes in non-@deprecated version of this class
-                SupBookRecord.class,
-                CRNCountRecord.class,
-                CRNRecord.class,
-                CFHeaderRecord.class,
-                CFRuleRecord.class,
-                TableRecord.class
-            };
-    }
-    private static Map           recordsMap  = recordsToMap(records);
+    private static final Class[] CONSTRUCTOR_ARGS = { RecordInputStream.class, };
 
+	/**
+     * contains the classes for all the records we want to parse.<br/>
+     * Note - this most but not *every* subclass of Record.
+     */
+    private static final Class[] records = {
+    	BackupRecord.class,
+    	BlankRecord.class,
+    	BOFRecord.class,
+    	BookBoolRecord.class,
+    	BoolErrRecord.class,
+    	BottomMarginRecord.class,
+    	BoundSheetRecord.class,
+    	CalcCountRecord.class,
+    	CalcModeRecord.class,
+    	CFHeaderRecord.class,
+    	CFRuleRecord.class,
+    	ChartRecord.class,
+    	ChartTitleFormatRecord.class,
+    	CodepageRecord.class,
+    	ColumnInfoRecord.class,
+    	ContinueRecord.class,
+    	CountryRecord.class,
+    	CRNCountRecord.class,
+    	CRNRecord.class,
+    	DateWindow1904Record.class,
+    	DBCellRecord.class,
+    	DefaultColWidthRecord.class,
+    	DefaultRowHeightRecord.class,
+    	DeltaRecord.class,
+    	DimensionsRecord.class,
+    	DrawingGroupRecord.class,
+    	DrawingRecord.class,
+    	DrawingSelectionRecord.class,
+    	DSFRecord.class,
+    	DVALRecord.class,
+    	DVRecord.class,
+    	EOFRecord.class,
+    	ExtendedFormatRecord.class,
+    	ExternalNameRecord.class,
+    	ExternSheetRecord.class,
+    	ExtSSTRecord.class,
+    	FilePassRecord.class,
+    	FileSharingRecord.class,
+    	FnGroupCountRecord.class,
+    	FontRecord.class,
+    	FooterRecord.class,
+    	FormatRecord.class,
+    	FormulaRecord.class,
+    	GridsetRecord.class,
+    	GutsRecord.class,
+    	HCenterRecord.class,
+    	HeaderRecord.class,
+    	HideObjRecord.class,
+    	HorizontalPageBreakRecord.class,
+    	HyperlinkRecord.class,
+    	IndexRecord.class,
+    	InterfaceEndRecord.class,
+    	InterfaceHdrRecord.class,
+    	IterationRecord.class,
+    	LabelRecord.class,
+    	LabelSSTRecord.class,
+    	LeftMarginRecord.class,
+    	LegendRecord.class,
+    	MergeCellsRecord.class,
+    	MMSRecord.class,
+    	MulBlankRecord.class,
+    	MulRKRecord.class,
+    	NameRecord.class,
+    	NoteRecord.class,
+    	NumberRecord.class,
+    	ObjectProtectRecord.class,
+    	ObjRecord.class,
+    	PaletteRecord.class,
+    	PaneRecord.class,
+    	PasswordRecord.class,
+    	PasswordRev4Record.class,
+    	PrecisionRecord.class,
+    	PrintGridlinesRecord.class,
+    	PrintHeadersRecord.class,
+    	PrintSetupRecord.class,
+    	ProtectionRev4Record.class,
+    	ProtectRecord.class,
+    	RecalcIdRecord.class,
+    	RefModeRecord.class,
+    	RefreshAllRecord.class,
+    	RightMarginRecord.class,
+    	RKRecord.class,
+    	RowRecord.class,
+    	SaveRecalcRecord.class,
+    	ScenarioProtectRecord.class,
+    	SelectionRecord.class,
+    	SeriesRecord.class,
+    	SeriesTextRecord.class,
+    	SharedFormulaRecord.class,
+    	SSTRecord.class,
+    	StringRecord.class,
+    	StyleRecord.class,
+    	SupBookRecord.class,
+    	TabIdRecord.class,
+    	TableRecord.class,
+    	TextObjectRecord.class,
+    	TopMarginRecord.class,
+    	UncalcedRecord.class,
+    	UseSelFSRecord.class,
+    	VCenterRecord.class,
+    	VerticalPageBreakRecord.class,
+    	WindowOneRecord.class,
+    	WindowProtectRecord.class,
+    	WindowTwoRecord.class,
+    	WriteAccessRecord.class,
+    	WriteProtectRecord.class,
+    	WSBoolRecord.class,
+    };
+    
     /**
-     * changes the default capacity (10000) to handle larger files
+     * cache of the recordsToMap();
      */
+    private static Map recordsMap  = recordsToMap(records);
 
-    public static void setCapacity(int capacity)
-    {
-        NUM_RECORDS = capacity;
-    }
-
+	private static short[] _allKnownRecordSIDs;
+    
     /**
-     * Create an array of records from an input stream
-     *
-     * @param in the InputStream from which the records will be
-     *           obtained
-     *
-     * @return an array of Records created from the InputStream
-     *
-     * @exception RecordFormatException on error processing the
-     *            InputStream
+     * create a record, if there are MUL records than multiple records
+     * are returned digested into the non-mul form.
      */
+    public static Record [] createRecord(RecordInputStream in) {
+        Constructor constructor = (Constructor) recordsMap.get(new Short(in.getSid()));
 
-    public static List createRecords(InputStream in)
-        throws RecordFormatException
-    {
-        ArrayList records     = new ArrayList(NUM_RECORDS);
-
-        RecordInputStream recStream = new RecordInputStream(in);
-            DrawingRecord lastDrawingRecord = new DrawingRecord( );
-        Record lastRecord = null;
-        while (recStream.hasNextRecord()) {
-          recStream.nextRecord();
-          if (recStream.getSid() != 0)
-            {
-              Record[] recs = createRecord(recStream);   // handle MulRK records
-
-                    if (recs.length > 1)
-                    {
-                        for (int k = 0; k < recs.length; k++)
-                        {
-                            records.add(
-                                recs[ k ]);               // these will be number records
-                  }
-                    }
-                    else
-                    {
-                        Record record = recs[ 0 ];
-
-                        if (record != null)
-                        {
-                        if (record.getSid() == DrawingGroupRecord.sid
-                            && lastRecord instanceof DrawingGroupRecord)
-                            {
-                            DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) lastRecord;
-                                lastDGRecord.join((AbstractEscherHolderRecord) record);
-                            }
-                        else if (record.getSid() == ContinueRecord.sid &&
-                                 ((lastRecord instanceof ObjRecord) || (lastRecord instanceof TextObjectRecord))) {
-                          // Drawing records have a very strange continue behaviour.
-                          //There can actually be OBJ records mixed between the continues.
-                          lastDrawingRecord.processContinueRecord( ((ContinueRecord)record).getData() );
-                            //we must rememeber the position of the continue record.
-                            //in the serialization procedure the original structure of records must be preserved
-                            records.add(record);
-                        } else if (record.getSid() == ContinueRecord.sid &&
-                                   (lastRecord instanceof DrawingGroupRecord)) {
-                            ((DrawingGroupRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
-                        } else if (record.getSid() == ContinueRecord.sid &&
-                        			(lastRecord instanceof StringRecord)) {
-                        	((StringRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
-                        } else if (record.getSid() == ContinueRecord.sid) {
-                          if (lastRecord instanceof UnknownRecord) {
-                            //Gracefully handle records that we dont know about,
-                            //that happen to be continued
-                            records.add(record);
-                          } else 
-                        	  throw new RecordFormatException("Unhandled Continue Record");
-                            }
-                        else {
-                            lastRecord = record;
-                                if (record instanceof DrawingRecord)
-                                    lastDrawingRecord = (DrawingRecord) record;
-                                records.add(record);
-                            }
-                        }
-                    }
-                }
-            }
-
-        return records;
-    }
-
-    public static Record [] createRecord(RecordInputStream in)
-    {
-        Record   retval;
-        Record[] realretval = null;
-
-        try
-        {
-            Constructor constructor =
-                ( Constructor ) recordsMap.get(new Short(in.getSid()));
-
-            if (constructor != null)
-            {
-                retval = ( Record ) constructor.newInstance(new Object[]
-                {
-                    in
-                });
-            }
-            else
-            {
-                retval = new UnknownRecord(in);
-            }
+        if (constructor == null) {
+            return new Record[] { new UnknownRecord(in), };
         }
-        catch (Exception introspectionException)
-        {
-            throw new RecordFormatException("Unable to construct record instance",introspectionException);
-        }
-        if (retval instanceof RKRecord)
-        {
+        
+        Record retval;
+
+        try {
+            retval = ( Record ) constructor.newInstance(new Object[] { in });
+        } catch (InvocationTargetException e) {
+            throw new RecordFormatException("Unable to construct record instance" , e.getTargetException());
+        } catch (IllegalArgumentException e) {
+			throw new RuntimeException(e);
+		} catch (InstantiationException e) {
+			throw new RuntimeException(e);
+		} catch (IllegalAccessException e) {
+			throw new RuntimeException(e);
+		}
+		
+        if (retval instanceof RKRecord) {
+        	// RK record is a slightly smaller alternative to NumberRecord
+        	// POI likes NumberRecord better
             RKRecord     rk  = ( RKRecord ) retval;
             NumberRecord num = new NumberRecord();
 
@@ -217,92 +201,174 @@
             num.setRow(rk.getRow());
             num.setXFIndex(rk.getXFIndex());
             num.setValue(rk.getRKNumber());
-            retval = num;
+            return new Record[] { num, };
         }
-        else if (retval instanceof DBCellRecord)
-        {
-            retval = null;
+        if (retval instanceof DBCellRecord) {
+        	// Not needed by POI.  Regenerated from scratch by POI when spreadsheet is written
+            return new Record[] { null, };
         }
-        else if (retval instanceof MulRKRecord)
-        {
+		// expand multiple records where necessary
+        if (retval instanceof MulRKRecord) {
             MulRKRecord mrk = ( MulRKRecord ) retval;
 
-            realretval = new Record[ mrk.getNumColumns() ];
-            for (int k = 0; k < mrk.getNumColumns(); k++)
-            {
+            Record[] mulRecs = new Record[ mrk.getNumColumns() ];
+            for (int k = 0; k < mrk.getNumColumns(); k++) {
                 NumberRecord nr = new NumberRecord();
 
                 nr.setColumn(( short ) (k + mrk.getFirstColumn()));
                 nr.setRow(mrk.getRow());
                 nr.setXFIndex(mrk.getXFAt(k));
                 nr.setValue(mrk.getRKNumberAt(k));
-                realretval[ k ] = nr;
+                mulRecs[ k ] = nr;
             }
+            return mulRecs;
         }
-        else if (retval instanceof MulBlankRecord)
-        {
+        if (retval instanceof MulBlankRecord) {
             MulBlankRecord mb = ( MulBlankRecord ) retval;
 
-            realretval = new Record[ mb.getNumColumns() ];
-            for (int k = 0; k < mb.getNumColumns(); k++)
-            {
+            Record[] mulRecs = new Record[ mb.getNumColumns() ];
+            for (int k = 0; k < mb.getNumColumns(); k++) {
                 BlankRecord br = new BlankRecord();
 
                 br.setColumn(( short ) (k + mb.getFirstColumn()));
                 br.setRow(mb.getRow());
                 br.setXFIndex(mb.getXFAt(k));
-                realretval[ k ] = br;
+                mulRecs[ k ] = br;
             }
+            return mulRecs;
         }
-        if (realretval == null)
-        {
-            realretval      = new Record[ 1 ];
-            realretval[ 0 ] = retval;
-        }
-        return realretval;
+        return new Record[] { retval, };
     }
 
-    public static short [] getAllKnownRecordSIDs()
-    {
-        short[] results = new short[ recordsMap.size() ];
-        int     i       = 0;
-
-        for (Iterator iterator = recordsMap.keySet().iterator();
-                iterator.hasNext(); )
-        {
-            Short sid = ( Short ) iterator.next();
+    /**
+     * @return an array of all the SIDS for all known records
+     */
+    public static short[] getAllKnownRecordSIDs() {
+    	if (_allKnownRecordSIDs == null) {
+            short[] results = new short[ recordsMap.size() ];
+            int i = 0;
 
-            results[ i++ ] = sid.shortValue();
-        }
-        return results;
-    }
+            for (Iterator iterator = recordsMap.keySet().iterator(); iterator.hasNext(); ) {
+                Short sid = (Short) iterator.next();
 
-    private static Map recordsToMap(Class [] records)
-    {
-        Map         result = new HashMap();
-        Constructor constructor;
-
-        for (int i = 0; i < records.length; i++)
-        {
-            Class record;
-            short sid;
+                results[i++] = sid.shortValue();
+            }
+            Arrays.sort(results);
+ 			_allKnownRecordSIDs = results;
+		}
 
-            record = records[ i ];
-            try
-            {
-                sid         = record.getField("sid").getShort(null);
-                constructor = record.getConstructor(new Class[]
-                {
-                    RecordInputStream.class
-                });
+		return (short[]) _allKnownRecordSIDs.clone();
+    }
+
+    /**
+     * gets the record constructors and sticks them in the map by SID
+     * @return map of SIDs to short,short,byte[] constructors for Record classes
+     * most of org.apache.poi.hssf.record.*
+     */
+    private static Map recordsToMap(Class [] records) {
+        Map result = new HashMap();
+        Set uniqueRecClasses = new HashSet(records.length * 3 / 2);
+
+        for (int i = 0; i < records.length; i++) {
+
+            Class recClass = records[ i ];
+            String cn = recClass.getName();
+			System.out.println(cn.substring(cn.lastIndexOf('.')+1) + ".class,");
+            if(!Record.class.isAssignableFrom(recClass)) {
+                throw new RuntimeException("Invalid record sub-class (" + cn + ")");
+            }
+            if(Modifier.isAbstract(recClass.getModifiers())) {
+                throw new RuntimeException("Invalid record class (" + cn + ") - must not be abstract");
+            }
+            if(!uniqueRecClasses.add(recClass)) {
+                throw new RuntimeException("duplicate record class (" + cn + ")");
             }
-            catch (Exception illegalArgumentException)
-            {
+            
+            short sid;
+            Constructor constructor;
+            try {
+                sid         = recClass.getField("sid").getShort(null);
+                constructor = recClass.getConstructor(CONSTRUCTOR_ARGS);
+            } catch (Exception illegalArgumentException) {
                 throw new RecordFormatException(
-                    "Unable to determine record types", illegalArgumentException);
+                    "Unable to determine record types");
+            }
+            Short key = new Short(sid);
+			if (result.containsKey(key)) {
+            	Class prev = (Class)result.get(key);
+                throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase()
+                		+ " for classes (" + cn + ") and (" + prev.getName() + ")");
             }
-            result.put(new Short(sid), constructor);
+            result.put(key, constructor);
         }
         return result;
     }
+
+    /**
+     * Create an array of records from an input stream
+     *
+     * @param in the InputStream from which the records will be obtained
+     *
+     * @return an array of Records created from the InputStream
+     *
+     * @exception RecordFormatException on error processing the InputStream
+     */
+    public static List createRecords(InputStream in) throws RecordFormatException {
+
+        List records = new ArrayList(NUM_RECORDS);
+
+        RecordInputStream recStream = new RecordInputStream(in);
+        DrawingRecord lastDrawingRecord = new DrawingRecord( );
+        Record lastRecord = null;
+        while (recStream.hasNextRecord()) {
+            recStream.nextRecord();
+            if (recStream.getSid() != 0) {
+                Record[] recs = createRecord(recStream);   // handle MulRK records
+
+                if (recs.length > 1) {
+                    for (int k = 0; k < recs.length; k++) {
+                    	records.add(recs[ k ]);               // these will be number records
+                    }
+                } else {
+                    Record record = recs[ 0 ];
+
+                    if (record != null) {
+                        if (record.getSid() == DrawingGroupRecord.sid
+                               && lastRecord instanceof DrawingGroupRecord) {
+                        	DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) lastRecord;
+                        	lastDGRecord.join((AbstractEscherHolderRecord) record);
+                        } else if (record.getSid() == ContinueRecord.sid &&
+                                 ((lastRecord instanceof ObjRecord) || (lastRecord instanceof TextObjectRecord))) {
+                            // Drawing records have a very strange continue behaviour.
+                        	//There can actually be OBJ records mixed between the continues.
+                        	lastDrawingRecord.processContinueRecord( ((ContinueRecord)record).getData() );
+                        	//we must remember the position of the continue record.
+                        	//in the serialization procedure the original structure of records must be preserved
+                        	records.add(record);
+                        } else if (record.getSid() == ContinueRecord.sid &&
+                                (lastRecord instanceof DrawingGroupRecord)) {
+                            ((DrawingGroupRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
+                        } else if (record.getSid() == ContinueRecord.sid &&
+                                (lastRecord instanceof StringRecord)) {
+                            ((StringRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
+                        } else if (record.getSid() == ContinueRecord.sid) {
+                            if (lastRecord instanceof UnknownRecord) {
+                                //Gracefully handle records that we dont know about,
+                            	//that happen to be continued
+                            	records.add(record);
+                            } else 
+                                throw new RecordFormatException("Unhandled Continue Record");
+                        } else {
+                            lastRecord = record;
+                            if (record instanceof DrawingRecord) {
+								lastDrawingRecord = (DrawingRecord) record;
+							}
+                            records.add(record);
+                        }
+                    }
+                }
+            }
+        }
+        return records;
+    }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java Mon Aug  4 14:08:11 2008
@@ -22,7 +22,6 @@
 import org.apache.poi.ddf.EscherBitmapBlip;
 import org.apache.poi.ddf.EscherRecord;
 import org.apache.poi.ddf.EscherBlipRecord;
-import org.apache.poi.hssf.eventmodel.EventRecordFactory;
 import org.apache.poi.hssf.model.Sheet;
 import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.*;
@@ -248,8 +247,6 @@
         //  it happens to be spelled.
         InputStream stream = directory.createDocumentInputStream(workbookName);
 
-        EventRecordFactory factory = new EventRecordFactory();
-
         List records = RecordFactory.createRecords(stream);
 
         workbook = Workbook.createWorkbook(records);

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/eventmodel/TestEventRecordFactory.java Mon Aug  4 14:08:11 2008
@@ -18,16 +18,16 @@
 package org.apache.poi.hssf.eventmodel;
 
 import java.io.ByteArrayInputStream;
-import java.util.Iterator;
+
+import junit.framework.TestCase;
 
 import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.ContinueRecord;
 import org.apache.poi.hssf.record.EOFRecord;
 import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.UnknownRecord;
-import org.apache.poi.hssf.record.ContinueRecord;
+import org.apache.poi.hssf.record.RecordFactory;
 import org.apache.poi.hssf.record.TestcaseRecordInputStream;
-
-import junit.framework.TestCase;
+import org.apache.poi.hssf.record.UnknownRecord;
 
 /**
  * enclosing_type describe the purpose here
@@ -35,63 +35,7 @@
  * @author Andrew C. Oliver acoliver@apache.org
  * @author Csaba Nagy (ncsaba at yahoo dot com)
  */
-public class TestEventRecordFactory extends TestCase
-{
-    boolean wascalled;
-
-    private EventRecordFactory factory;
-    /**
-     * Constructor for TestEventRecordFactory.
-     * @param arg0
-     */
-    public TestEventRecordFactory(String arg0)
-    {
-        super(arg0);
-    }
-
-    public static void main(String[] args)
-    {
-        junit.textui.TestRunner.run(TestEventRecordFactory.class);
-    }
-
-    protected void setUp() throws Exception
-    {
-        super.setUp();
-        factory = new EventRecordFactory();
-    }
-
-    protected void tearDown() throws Exception
-    {
-        super.tearDown();
-    }
-
-    /**
-     * tests that a listener can be registered and that once
-     * registered can be returned as expected.
-     */
-    public void testRegisterListener()
-    {        
-        factory.registerListener(new ERFListener() {
-            public boolean processRecord(Record rec) {
-              return true;   
-            }
-        },null);
-        
-        Iterator i = factory.listeners();
-        assertTrue("iterator must have one",i.hasNext());
-       
-        factory.registerListener(new ERFListener() {
-            public boolean processRecord(Record rec) {
-              return true;   
-            }
-        },null);
-        
-        i = factory.listeners();
-        
-        i.next();      
-        assertTrue("iterator must have two",i.hasNext());         
-        factory = new EventRecordFactory();
-    }
+public final class TestEventRecordFactory extends TestCase {
 
     /**
      * tests that the records can be processed and properly return 
@@ -99,17 +43,17 @@
      */
     public void testProcessRecords()
     {
-        byte[] bytes = null;
-        int offset = 0;
-        //boolean wascalled = false;
-        factory.registerListener(new ERFListener() {
+        final boolean[] wascalled = { false, }; // hack to pass boolean by ref into inner class
+
+        ERFListener listener = new ERFListener() {
             public boolean processRecord(Record rec) {
-                wascalled = true;
+                wascalled[0] = true;
                 assertTrue("must be BOFRecord got SID="+rec.getSid(),
                            (rec.getSid() == BOFRecord.sid));                  
                 return true;              
             }
-        }, new short[] {BOFRecord.sid});
+        };
+    	EventRecordFactory factory = new EventRecordFactory(listener, new short[] {BOFRecord.sid});
         
         BOFRecord bof = new BOFRecord();
         bof.setBuild((short)0);
@@ -120,23 +64,20 @@
         bof.setHistoryBitMask(BOFRecord.HISTORY_MASK);
         
         EOFRecord eof = new EOFRecord();
-        bytes = new byte[bof.getRecordSize() + eof.getRecordSize()];
+    	byte[] bytes = new byte[bof.getRecordSize() + eof.getRecordSize()];
+        int offset = 0;
         offset = bof.serialize(offset,bytes);
         offset = eof.serialize(offset,bytes);
                 
         factory.processRecords(new ByteArrayInputStream(bytes));    
-        assertTrue("The record listener must be called",wascalled);    
+        assertTrue("The record listener must be called", wascalled[0]);    
     }
 
     /**
      * tests that the create record function returns a properly 
      * constructed record in the simple case.
      */
-    public void testCreateRecord()
-    {
-        byte[] bytes = null;
-        byte[] nbytes = null;
-        Record[] records = null;
+    public void testCreateRecord() {
         BOFRecord bof = new BOFRecord();
         bof.setBuild((short)0);
         bof.setBuildYear((short)1999);
@@ -145,11 +86,11 @@
         bof.setVersion((short)0x06);
         bof.setHistoryBitMask(BOFRecord.HISTORY_MASK);
         
-        bytes = bof.serialize();
-        nbytes = new byte[bytes.length - 4];
+        byte[] bytes = bof.serialize();
+        byte[] nbytes = new byte[bytes.length - 4];
         System.arraycopy(bytes,4,nbytes,0,nbytes.length);
             
-        records = factory.createRecord(new TestcaseRecordInputStream(bof.getSid(),(short)nbytes.length,nbytes));
+        Record[] records = RecordFactory.createRecord(new TestcaseRecordInputStream(bof.getSid(),(short)nbytes.length,nbytes));
         
         assertTrue("record.length must be 1, was ="+records.length,records.length == 1);
         assertTrue("record is the same", compareRec(bof,records[0]));
@@ -162,24 +103,19 @@
      * @param second the second record to compare
      * @return boolean whether or not the record where equal
      */
-    private boolean compareRec(Record first, Record second)
-    {
-        boolean retval = true;
+    private static boolean compareRec(Record first, Record second) {
         byte[] rec1 = first.serialize();
         byte[] rec2 = second.serialize();
         
-        if (rec1.length == rec2.length) {
-            for (int k=0; k<rec1.length; k++) {
-             if (rec1[k] != rec2[k]) {
-              retval = false;
-              break;  
-             }   
-            }
-        } else {
-            retval = false;   
+        if (rec1.length != rec2.length) {
+            return false;   
         }
-        
-        return retval;
+        for (int k=0; k<rec1.length; k++) {
+            if (rec1[k] != rec2[k]) {
+                return false;
+            }   
+        }
+        return true;
     }
 
     
@@ -202,10 +138,8 @@
      * FAILURE:    The wrong records are created or contain the wrong values <P>
      *
      */
-     public void testContinuedUnknownRecord()
-     {
-        final byte[]   data    = new byte[]
-        {
+     public void testContinuedUnknownRecord() {
+        final byte[] data = {
             0, -1, 0, 0, // an unknown record with 0 length
             0x3C , 0, 3, 0, 1, 2, 3, // a continuation record with 3 bytes of data
             0x3C , 0, 1, 0, 4 // one more continuation record with 1 byte of data
@@ -213,8 +147,7 @@
 
         final int[] recCnt = { 0 };
         final int[] offset = { 0 };
-        factory.registerListener(
-          new ERFListener() {
+        ERFListener listener = new ERFListener() {
               private String[] expectedRecordTypes = {
                   UnknownRecord.class.getName(),
                   ContinueRecord.class.getName(),
@@ -238,14 +171,11 @@
                       assertEquals(message + " data byte " + i, data[offset[0]++], recData[i]);
                   }
               }
-          },
-          new short[] {-256, 0x3C}
-        );
+          };
+    	EventRecordFactory factory = new EventRecordFactory(listener, new short[] {-256, 0x3C});
 
         factory.processRecords(new ByteArrayInputStream(data));
         assertEquals("nr. of processed records", 3, recCnt[0]);
         assertEquals("nr. of processed bytes", data.length, offset[0]);
     }
-
-
 }

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestSheet.java Mon Aug  4 14:08:11 2008
@@ -416,9 +416,9 @@
         int size = sheet.getSize();
         byte[] data = new byte[size];
         sheet.serialize(0, data);
-        EventRecordFactory erf = new EventRecordFactory();
+
         MyIndexRecordListener myIndexListener = new MyIndexRecordListener();
-        erf.registerListener(myIndexListener, new short[] { IndexRecord.sid, });
+        EventRecordFactory erf = new EventRecordFactory(myIndexListener, new short[] { IndexRecord.sid, });
         erf.processRecords(new ByteArrayInputStream(data));
         IndexRecord indexRecord = myIndexListener.getIndexRecord();
         int dbCellRecordPos = indexRecord.getDbcellAt(0);

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java?rev=682508&r1=682507&r2=682508&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestDataValidation.java Mon Aug  4 14:08:11 2008
@@ -594,9 +594,9 @@
 		byte[] wbData = baos.toByteArray();
 		
 		if (false) { // TODO (Jul 2008) fix EventRecordFactory to process unknown records, (and DV records for that matter)
-			EventRecordFactory erf = new EventRecordFactory();
+
 			ERFListener erfListener = null; // new MyERFListener();
-			erf.registerListener(erfListener, null);
+			EventRecordFactory erf = new EventRecordFactory(erfListener, null);
 			try {
 				POIFSFileSystem fs = new POIFSFileSystem(new ByteArrayInputStream(baos.toByteArray()));
 				erf.processRecords(fs.createDocumentInputStream("Workbook"));



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


Mime
View raw message