1 2 17 18 19 package org.apache.poi.hssf.record; 20 21 import org.apache.poi.util.LittleEndian; 22 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.lang.reflect.Constructor ; 26 import java.util.*; 27 28 40 41 public class RecordFactory 42 { 43 private static int NUM_RECORDS = 10000; 44 private static final Class [] records; 45 46 static { 47 if (FormulaRecord.EXPERIMENTAL_FORMULA_SUPPORT_ENABLED) { 48 records = new Class [] 49 { 50 BOFRecord.class, InterfaceHdrRecord.class, MMSRecord.class, 51 InterfaceEndRecord.class, WriteAccessRecord.class, 52 CodepageRecord.class, DSFRecord.class, TabIdRecord.class, 53 FnGroupCountRecord.class, WindowProtectRecord.class, 54 ProtectRecord.class, PasswordRecord.class, ProtectionRev4Record.class, 55 PasswordRev4Record.class, WindowOneRecord.class, BackupRecord.class, 56 HideObjRecord.class, DateWindow1904Record.class, 57 PrecisionRecord.class, RefreshAllRecord.class, BookBoolRecord.class, 58 FontRecord.class, FormatRecord.class, ExtendedFormatRecord.class, 59 StyleRecord.class, UseSelFSRecord.class, BoundSheetRecord.class, 60 CountryRecord.class, SSTRecord.class, ExtSSTRecord.class, 61 EOFRecord.class, IndexRecord.class, CalcModeRecord.class, 62 CalcCountRecord.class, RefModeRecord.class, IterationRecord.class, 63 DeltaRecord.class, SaveRecalcRecord.class, PrintHeadersRecord.class, 64 PrintGridlinesRecord.class, GridsetRecord.class, GutsRecord.class, 65 DefaultRowHeightRecord.class, WSBoolRecord.class, HeaderRecord.class, 66 FooterRecord.class, HCenterRecord.class, VCenterRecord.class, 67 PrintSetupRecord.class, DefaultColWidthRecord.class, 68 DimensionsRecord.class, RowRecord.class, LabelSSTRecord.class, 69 RKRecord.class, NumberRecord.class, DBCellRecord.class, 70 WindowTwoRecord.class, SelectionRecord.class, ContinueRecord.class, 71 LabelRecord.class, BlankRecord.class, ColumnInfoRecord.class, 72 MulRKRecord.class, MulBlankRecord.class, MergeCellsRecord.class, 73 FormulaRecord.class, BoolErrRecord.class, ExternSheetRecord.class, 74 NameRecord.class, LeftMarginRecord.class, RightMarginRecord.class, 75 TopMarginRecord.class, BottomMarginRecord.class, 76 DrawingRecord.class, DrawingGroupRecord.class, DrawingSelectionRecord.class, 77 ObjRecord.class, TextObjectRecord.class, 78 PaletteRecord.class, StringRecord.class, RecalcIdRecord.class, SharedFormulaRecord.class, 79 HorizontalPageBreakRecord.class, VerticalPageBreakRecord.class 80 }; 81 } else { 82 records = new Class [] 83 { 84 BOFRecord.class, InterfaceHdrRecord.class, MMSRecord.class, 85 InterfaceEndRecord.class, WriteAccessRecord.class, 86 CodepageRecord.class, DSFRecord.class, TabIdRecord.class, 87 FnGroupCountRecord.class, WindowProtectRecord.class, 88 ProtectRecord.class, PasswordRecord.class, ProtectionRev4Record.class, 89 PasswordRev4Record.class, WindowOneRecord.class, BackupRecord.class, 90 HideObjRecord.class, DateWindow1904Record.class, 91 PrecisionRecord.class, RefreshAllRecord.class, BookBoolRecord.class, 92 FontRecord.class, FormatRecord.class, ExtendedFormatRecord.class, 93 StyleRecord.class, UseSelFSRecord.class, BoundSheetRecord.class, 94 CountryRecord.class, SSTRecord.class, ExtSSTRecord.class, 95 EOFRecord.class, IndexRecord.class, CalcModeRecord.class, 96 CalcCountRecord.class, RefModeRecord.class, IterationRecord.class, 97 DeltaRecord.class, SaveRecalcRecord.class, PrintHeadersRecord.class, 98 PrintGridlinesRecord.class, GridsetRecord.class, GutsRecord.class, 99 DefaultRowHeightRecord.class, WSBoolRecord.class, HeaderRecord.class, 100 FooterRecord.class, HCenterRecord.class, VCenterRecord.class, 101 PrintSetupRecord.class, DefaultColWidthRecord.class, 102 DimensionsRecord.class, RowRecord.class, LabelSSTRecord.class, 103 RKRecord.class, NumberRecord.class, DBCellRecord.class, 104 WindowTwoRecord.class, SelectionRecord.class, ContinueRecord.class, 105 LabelRecord.class, BlankRecord.class, ColumnInfoRecord.class, 106 MulRKRecord.class, MulBlankRecord.class, MergeCellsRecord.class, 107 BoolErrRecord.class, ExternSheetRecord.class, NameRecord.class, 108 LeftMarginRecord.class, RightMarginRecord.class, 109 TopMarginRecord.class, BottomMarginRecord.class, 110 PaletteRecord.class, StringRecord.class, RecalcIdRecord.class, SharedFormulaRecord.class, 111 DrawingRecord.class, DrawingGroupRecord.class, DrawingSelectionRecord.class, 112 ObjRecord.class, TextObjectRecord.class, 113 HorizontalPageBreakRecord.class, VerticalPageBreakRecord.class 114 }; 115 116 } 117 } 118 private static Map recordsMap = recordsToMap(records); 119 120 123 124 public static void setCapacity(int capacity) 125 { 126 NUM_RECORDS = capacity; 127 } 128 129 140 141 public static List createRecords(InputStream in) 142 throws RecordFormatException 143 { 144 ArrayList records = new ArrayList(NUM_RECORDS); 145 Record last_record = null; 146 147 try 148 { 149 short rectype = 0; 150 151 do 152 { 153 rectype = LittleEndian.readShort(in); 154 if (rectype != 0) 155 { 156 short recsize = LittleEndian.readShort(in); 157 byte[] data = new byte[ ( int ) recsize ]; 158 159 in.read(data); 160 Record[] recs = createRecord(rectype, recsize, 161 data); 163 if (recs.length > 1) 164 { 165 for (int k = 0; k < recs.length; k++) 166 { 167 records.add( 168 recs[ k ]); last_record = 170 recs[ k ]; } } 173 else 174 { 175 Record record = recs[ 0 ]; 176 177 if (record != null) 178 { 179 if (rectype == ContinueRecord.sid && 180 ! (last_record instanceof ContinueRecord) && ! (last_record instanceof UnknownRecord) ) { 183 if (last_record == null) 184 { 185 throw new RecordFormatException( 186 "First record is a ContinueRecord??"); 187 } 188 last_record.processContinueRecord(data); 189 } 190 else 191 { 192 last_record = record; 193 records.add(record); 194 } 195 } 196 } 197 } 198 } 199 while (rectype != 0); 200 } 201 catch (IOException e) 202 { 203 throw new RecordFormatException("Error reading bytes"); 204 } 205 206 return records; 209 } 210 211 public static Record [] createRecord(short rectype, short size, 212 byte [] data) 213 { 214 Record retval = null; 215 Record[] realretval = null; 216 217 try 218 { 219 Constructor constructor = 220 ( Constructor ) recordsMap.get(new Short (rectype)); 221 222 if (constructor != null) 223 { 224 retval = ( Record ) constructor.newInstance(new Object [] 225 { 226 new Short (rectype), new Short (size), data 227 }); 228 } 229 else 230 { 231 retval = new UnknownRecord(rectype, size, data); 232 } 233 } 234 catch (Exception introspectionException) 235 { 236 237 } 241 if (retval instanceof RKRecord) 242 { 243 RKRecord rk = ( RKRecord ) retval; 244 NumberRecord num = new NumberRecord(); 245 246 num.setColumn(rk.getColumn()); 247 num.setRow(rk.getRow()); 248 num.setXFIndex(rk.getXFIndex()); 249 num.setValue(rk.getRKNumber()); 250 retval = num; 251 } 252 else if (retval instanceof DBCellRecord) 253 { 254 retval = null; 255 } 256 else if (retval instanceof MulRKRecord) 257 { 258 MulRKRecord mrk = ( MulRKRecord ) retval; 259 260 realretval = new Record[ mrk.getNumColumns() ]; 261 for (int k = 0; k < mrk.getNumColumns(); k++) 262 { 263 NumberRecord nr = new NumberRecord(); 264 265 nr.setColumn(( short ) (k + mrk.getFirstColumn())); 266 nr.setRow(mrk.getRow()); 267 nr.setXFIndex(mrk.getXFAt(k)); 268 nr.setValue(mrk.getRKNumberAt(k)); 269 realretval[ k ] = nr; 270 } 271 } 272 else if (retval instanceof MulBlankRecord) 273 { 274 MulBlankRecord mb = ( MulBlankRecord ) retval; 275 276 realretval = new Record[ mb.getNumColumns() ]; 277 for (int k = 0; k < mb.getNumColumns(); k++) 278 { 279 BlankRecord br = new BlankRecord(); 280 281 br.setColumn(( short ) (k + mb.getFirstColumn())); 282 br.setRow(mb.getRow()); 283 br.setXFIndex(mb.getXFAt(k)); 284 realretval[ k ] = br; 285 } 286 } 287 if (realretval == null) 288 { 289 realretval = new Record[ 1 ]; 290 realretval[ 0 ] = retval; 291 } 292 return realretval; 293 } 294 295 public static short [] getAllKnownRecordSIDs() 296 { 297 short[] results = new short[ recordsMap.size() ]; 298 int i = 0; 299 300 for (Iterator iterator = recordsMap.keySet().iterator(); 301 iterator.hasNext(); ) 302 { 303 Short sid = ( Short ) iterator.next(); 304 305 results[ i++ ] = sid.shortValue(); 306 } 307 return results; 308 } 309 310 private static Map recordsToMap(Class [] records) 311 { 312 Map result = new HashMap(); 313 Constructor constructor; 314 315 for (int i = 0; i < records.length; i++) 316 { 317 Class record = null; 318 short sid = 0; 319 320 record = records[ i ]; 321 try 322 { 323 sid = record.getField("sid").getShort(null); 324 constructor = record.getConstructor(new Class [] 325 { 326 short.class, short.class, byte [].class 327 }); 328 } 329 catch (Exception illegalArgumentException) 330 { 331 illegalArgumentException.printStackTrace(); 332 throw new RecordFormatException( 333 "Unable to determine record types"); 334 } 335 result.put(new Short (sid), constructor); 336 } 337 return result; 338 } 339 } 340 | Popular Tags |