FileDocCategorySizeDatePackage
EventRecordFactory.javaAPI DocApache Poi 3.0.118195Mon Jan 01 18:59:10 GMT 2007org.apache.poi.hssf.eventmodel

EventRecordFactory

public class EventRecordFactory extends Object
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.
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)

Fields Summary
private static final Class[]
records
contains the classes for all the records we want to parse.
private static Map
recordsMap
cache of the recordsToMap();
private static short[]
sidscache
cache of the return of getAllKnownSids so that we don't have to expensively get them every time.
private List
listeners
List of the listners that are registred. should all be ERFListener
private boolean
abortable
instance is abortable or not
Constructors Summary
public EventRecordFactory()
Construct an abortable EventRecordFactory. The same as calling new EventRecordFactory(true)

see
#EventRecordFactory(boolean)

    
                       
      
        this(true);                  
    
public EventRecordFactory(boolean abortable)
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.

        this.abortable = abortable;
        listeners = new ArrayList(recordsMap.size());    
        
        if (sidscache == null) {
         sidscache = getAllKnownRecordSIDs();   
        }

    
Methods Summary
public static org.apache.poi.hssf.record.Record[]createRecord(org.apache.poi.hssf.record.RecordInputStream in)
create a record, if there are MUL records than multiple records are returned digested into the non-mul form.

        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;
    
public static short[]getAllKnownRecordSIDs()

return
an array of all the SIDS for all known records

        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;
    
protected java.util.Iteratorlisteners()
used for unit tests to test the registration of record listeners.

return
Iterator of ERFListeners

        return listeners.iterator();
    
public voidprocessRecords(java.io.InputStream in)
Create an array of records from an input stream

param
in the InputStream from which the records will be obtained
exception
RecordFormatException on error processing the InputStream

        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.
                    }
                    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;
                            }
                        }
                    }

            
            if (last_record != null) {
               throwRecordEvent(last_record);               
            }
        
private static java.util.MaprecordsToMap(java.lang.Class[] records)
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.*

        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");
            }
            result.put(new Short(sid), constructor);
        }
        return result;
    
public voidregisterListener(org.apache.poi.hssf.eventmodel.ERFListener listener, 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.

      if (sids == null)
        sids = sidscache;
      ERFListener wrapped = new ListenerWrapper(listener, sids, abortable);    
      listeners.add(wrapped);
    
private booleanthrowRecordEvent(org.apache.poi.hssf.record.Record record)
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.

        boolean result = true;
        Iterator i = listeners.iterator();
        
        while (i.hasNext()) {
            result = ((ERFListener) i.next()).processRecord(record);  
            if (abortable == true && result == false) {
                break;   
            }
        }
        return result;