Save This Page
Home » poi-src-3.2-FINAL-20081019 » org.apache » poi » hssf » record » [javadoc | source]
    1   
    2   /* ====================================================================
    3      Licensed to the Apache Software Foundation (ASF) under one or more
    4      contributor license agreements.  See the NOTICE file distributed with
    5      this work for additional information regarding copyright ownership.
    6      The ASF licenses this file to You under the Apache License, Version 2.0
    7      (the "License"); you may not use this file except in compliance with
    8      the License.  You may obtain a copy of the License at
    9   
   10          http://www.apache.org/licenses/LICENSE-2.0
   11   
   12      Unless required by applicable law or agreed to in writing, software
   13      distributed under the License is distributed on an "AS IS" BASIS,
   14      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15      See the License for the specific language governing permissions and
   16      limitations under the License.
   17   ==================================================================== */
   18           
   19   
   20   package org.apache.poi.hssf.record;
   21   
   22   import java.io.InputStream;
   23   import java.lang.reflect.Constructor;
   24   import java.util;
   25   
   26   /**
   27    * Title:  Record Factory<P>
   28    * Description:  Takes a stream and outputs an array of Record objects.<P>
   29    *
   30    * @deprecated use {@link org.apache.poi.hssf.eventmodel.EventRecordFactory} instead
   31    * @see org.apache.poi.hssf.eventmodel.EventRecordFactory
   32    * @author Andrew C. Oliver (acoliver at apache dot org)
   33    * @author Marc Johnson (mjohnson at apache dot org)
   34    * @author Glen Stampoultzis (glens at apache.org)
   35    * @author Csaba Nagy (ncsaba at yahoo dot com)
   36    */
   37   
   38   public class RecordFactory
   39   {
   40       private static int           NUM_RECORDS = 10000;
   41       private static final Class[] records;
   42   
   43       static {
   44               records = new Class[]
   45               {
   46                   BOFRecord.class, InterfaceHdrRecord.class, MMSRecord.class,
   47                   InterfaceEndRecord.class, WriteAccessRecord.class,
   48                   CodepageRecord.class, DSFRecord.class, TabIdRecord.class,
   49                   FnGroupCountRecord.class, WindowProtectRecord.class,
   50                   ProtectRecord.class, PasswordRecord.class, ProtectionRev4Record.class,
   51                   PasswordRev4Record.class, WindowOneRecord.class, BackupRecord.class,
   52                   HideObjRecord.class, DateWindow1904Record.class,
   53                   PrecisionRecord.class, RefreshAllRecord.class, BookBoolRecord.class,
   54                   FontRecord.class, FormatRecord.class, ExtendedFormatRecord.class,
   55                   StyleRecord.class, UseSelFSRecord.class, BoundSheetRecord.class,
   56                   CountryRecord.class, SSTRecord.class, ExtSSTRecord.class,
   57                   EOFRecord.class, IndexRecord.class, CalcModeRecord.class,
   58                   CalcCountRecord.class, RefModeRecord.class, IterationRecord.class,
   59                   DeltaRecord.class, SaveRecalcRecord.class, PrintHeadersRecord.class,
   60                   PrintGridlinesRecord.class, GridsetRecord.class, GutsRecord.class,
   61                   DefaultRowHeightRecord.class, WSBoolRecord.class, HeaderRecord.class,
   62                   FooterRecord.class, HCenterRecord.class, VCenterRecord.class,
   63                   PrintSetupRecord.class, DefaultColWidthRecord.class,
   64                   DimensionsRecord.class, RowRecord.class, LabelSSTRecord.class,
   65                   RKRecord.class, NumberRecord.class, DBCellRecord.class,
   66                   WindowTwoRecord.class, SelectionRecord.class, ContinueRecord.class,
   67                   LabelRecord.class, BlankRecord.class, ColumnInfoRecord.class,
   68                   MulRKRecord.class, MulBlankRecord.class, MergeCellsRecord.class,
   69                   FormulaRecord.class, BoolErrRecord.class, ExternSheetRecord.class,
   70                   NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class,
   71                   TopMarginRecord.class, BottomMarginRecord.class,
   72                   DrawingRecord.class, DrawingGroupRecord.class, DrawingSelectionRecord.class,
   73                   ObjRecord.class, TextObjectRecord.class,
   74                   PaletteRecord.class, StringRecord.class, RecalcIdRecord.class, SharedFormulaRecord.class,
   75                   HorizontalPageBreakRecord.class, VerticalPageBreakRecord.class, 
   76                   WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class,
   77                   NoteRecord.class, ObjectProtectRecord.class, ScenarioProtectRecord.class, 
   78                   FileSharingRecord.class, ChartTitleFormatRecord.class,
   79                   DVRecord.class, DVALRecord.class, UncalcedRecord.class,
   80                   ChartRecord.class, LegendRecord.class, ChartTitleFormatRecord.class, 
   81                   SeriesRecord.class, SeriesTextRecord.class,
   82                   HyperlinkRecord.class,
   83                   ExternalNameRecord.class, // TODO - same changes in non-@deprecated version of this class
   84                   SupBookRecord.class,
   85                   CRNCountRecord.class,
   86                   CRNRecord.class,
   87                   CFHeaderRecord.class,
   88                   CFRuleRecord.class,
   89               };
   90       }
   91       private static Map           recordsMap  = recordsToMap(records);
   92   
   93       /**
   94        * changes the default capacity (10000) to handle larger files
   95        */
   96   
   97       public static void setCapacity(int capacity)
   98       {
   99           NUM_RECORDS = capacity;
  100       }
  101   
  102       /**
  103        * Create an array of records from an input stream
  104        *
  105        * @param in the InputStream from which the records will be
  106        *           obtained
  107        *
  108        * @return an array of Records created from the InputStream
  109        *
  110        * @exception RecordFormatException on error processing the
  111        *            InputStream
  112        */
  113   
  114       public static List createRecords(InputStream in)
  115           throws RecordFormatException
  116       {
  117           ArrayList records     = new ArrayList(NUM_RECORDS);
  118   
  119           RecordInputStream recStream = new RecordInputStream(in);
  120               DrawingRecord lastDrawingRecord = new DrawingRecord( );
  121           Record lastRecord = null;
  122           while (recStream.hasNextRecord()) {
  123             recStream.nextRecord();
  124             if (recStream.getSid() != 0)
  125               {
  126                 Record[] recs = createRecord(recStream);   // handle MulRK records
  127   
  128                       if (recs.length > 1)
  129                       {
  130                           for (int k = 0; k < recs.length; k++)
  131                           {
  132                               records.add(
  133                                   recs[ k ]);               // these will be number records
  134                     }
  135                       }
  136                       else
  137                       {
  138                           Record record = recs[ 0 ];
  139   
  140                           if (record != null)
  141                           {
  142                           if (record.getSid() == DrawingGroupRecord.sid
  143                               && lastRecord instanceof DrawingGroupRecord)
  144                               {
  145                               DrawingGroupRecord lastDGRecord = (DrawingGroupRecord) lastRecord;
  146                                   lastDGRecord.join((AbstractEscherHolderRecord) record);
  147                               }
  148                           else if (record.getSid() == ContinueRecord.sid &&
  149                                    ((lastRecord instanceof ObjRecord) || (lastRecord instanceof TextObjectRecord))) {
  150                             // Drawing records have a very strange continue behaviour.
  151                             //There can actually be OBJ records mixed between the continues.
  152                             lastDrawingRecord.processContinueRecord( ((ContinueRecord)record).getData() );
  153                               //we must rememeber the position of the continue record.
  154                               //in the serialization procedure the original structure of records must be preserved
  155                               records.add(record);
  156                           } else if (record.getSid() == ContinueRecord.sid &&
  157                                      (lastRecord instanceof DrawingGroupRecord)) {
  158                               ((DrawingGroupRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
  159                           } else if (record.getSid() == ContinueRecord.sid &&
  160                           			(lastRecord instanceof StringRecord)) {
  161                           	((StringRecord)lastRecord).processContinueRecord(((ContinueRecord)record).getData());
  162                           } else if (record.getSid() == ContinueRecord.sid) {
  163                             if (lastRecord instanceof UnknownRecord) {
  164                               //Gracefully handle records that we dont know about,
  165                               //that happen to be continued
  166                               records.add(record);
  167                             } else 
  168                           	  throw new RecordFormatException("Unhandled Continue Record");
  169                               }
  170                           else {
  171                               lastRecord = record;
  172                                   if (record instanceof DrawingRecord)
  173                                       lastDrawingRecord = (DrawingRecord) record;
  174                                   records.add(record);
  175                               }
  176                           }
  177                       }
  178                   }
  179               }
  180   
  181           return records;
  182       }
  183   
  184       public static Record [] createRecord(RecordInputStream in)
  185       {
  186           Record   retval;
  187           Record[] realretval = null;
  188   
  189           try
  190           {
  191               Constructor constructor =
  192                   ( Constructor ) recordsMap.get(new Short(in.getSid()));
  193   
  194               if (constructor != null)
  195               {
  196                   retval = ( Record ) constructor.newInstance(new Object[]
  197                   {
  198                       in
  199                   });
  200               }
  201               else
  202               {
  203                   retval = new UnknownRecord(in);
  204               }
  205           }
  206           catch (Exception introspectionException)
  207           {
  208               throw new RecordFormatException("Unable to construct record instance",introspectionException);
  209           }
  210           if (retval instanceof RKRecord)
  211           {
  212               RKRecord     rk  = ( RKRecord ) retval;
  213               NumberRecord num = new NumberRecord();
  214   
  215               num.setColumn(rk.getColumn());
  216               num.setRow(rk.getRow());
  217               num.setXFIndex(rk.getXFIndex());
  218               num.setValue(rk.getRKNumber());
  219               retval = num;
  220           }
  221           else if (retval instanceof DBCellRecord)
  222           {
  223               retval = null;
  224           }
  225           else if (retval instanceof MulRKRecord)
  226           {
  227               MulRKRecord mrk = ( MulRKRecord ) retval;
  228   
  229               realretval = new Record[ mrk.getNumColumns() ];
  230               for (int k = 0; k < mrk.getNumColumns(); k++)
  231               {
  232                   NumberRecord nr = new NumberRecord();
  233   
  234                   nr.setColumn(( short ) (k + mrk.getFirstColumn()));
  235                   nr.setRow(mrk.getRow());
  236                   nr.setXFIndex(mrk.getXFAt(k));
  237                   nr.setValue(mrk.getRKNumberAt(k));
  238                   realretval[ k ] = nr;
  239               }
  240           }
  241           else if (retval instanceof MulBlankRecord)
  242           {
  243               MulBlankRecord mb = ( MulBlankRecord ) retval;
  244   
  245               realretval = new Record[ mb.getNumColumns() ];
  246               for (int k = 0; k < mb.getNumColumns(); k++)
  247               {
  248                   BlankRecord br = new BlankRecord();
  249   
  250                   br.setColumn(( short ) (k + mb.getFirstColumn()));
  251                   br.setRow(mb.getRow());
  252                   br.setXFIndex(mb.getXFAt(k));
  253                   realretval[ k ] = br;
  254               }
  255           }
  256           if (realretval == null)
  257           {
  258               realretval      = new Record[ 1 ];
  259               realretval[ 0 ] = retval;
  260           }
  261           return realretval;
  262       }
  263   
  264       public static short [] getAllKnownRecordSIDs()
  265       {
  266           short[] results = new short[ recordsMap.size() ];
  267           int     i       = 0;
  268   
  269           for (Iterator iterator = recordsMap.keySet().iterator();
  270                   iterator.hasNext(); )
  271           {
  272               Short sid = ( Short ) iterator.next();
  273   
  274               results[ i++ ] = sid.shortValue();
  275           }
  276           return results;
  277       }
  278   
  279       private static Map recordsToMap(Class [] records)
  280       {
  281           Map         result = new HashMap();
  282           Constructor constructor;
  283   
  284           for (int i = 0; i < records.length; i++)
  285           {
  286               Class record;
  287               short sid;
  288   
  289               record = records[ i ];
  290               try
  291               {
  292                   sid         = record.getField("sid").getShort(null);
  293                   constructor = record.getConstructor(new Class[]
  294                   {
  295                       RecordInputStream.class
  296                   });
  297               }
  298               catch (Exception illegalArgumentException)
  299               {
  300                   throw new RecordFormatException(
  301                       "Unable to determine record types", illegalArgumentException);
  302               }
  303               result.put(new Short(sid), constructor);
  304           }
  305           return result;
  306       }
  307   }

Save This Page
Home » poi-src-3.2-FINAL-20081019 » org.apache » poi » hssf » record » [javadoc | source]