1 2 17 18 19 package org.apache.poi.hssf.usermodel; 20 21 import junit.framework.Assert; 22 import org.apache.poi.hssf.model.Sheet; 23 import org.apache.poi.hssf.model.Workbook; 24 import org.apache.poi.hssf.record.*; 25 26 import java.util.List ; 27 28 31 public class SanityChecker 32 extends Assert 33 { 34 static class CheckRecord 35 { 36 Class record; 37 char occurance; private boolean together; 39 40 public CheckRecord( Class record, char occurance ) 41 { 42 this(record, occurance, true); 43 } 44 45 50 public CheckRecord(Class record, char occurance, boolean together) 51 { 52 this.record = record; 53 this.occurance = occurance; 54 this.together = together; 55 } 56 57 public Class getRecord() 58 { 59 return record; 60 } 61 62 public char getOccurance() 63 { 64 return occurance; 65 } 66 67 public boolean isRequired() 68 { 69 return occurance == '1' || occurance == 'M'; 70 } 71 72 public boolean isOptional() 73 { 74 return occurance == '0' || occurance == '*'; 75 } 76 77 public boolean isTogether() 78 { 79 return together; 80 } 81 82 public boolean isMany() 83 { 84 return occurance == '*' || occurance == 'M'; 85 } 86 87 public int match( List records, int recordIdx ) 88 { 89 int firstRecord = findFirstRecord(records, getRecord(), recordIdx); 90 if (isRequired()) 91 { 92 return matchRequired( firstRecord, records, recordIdx ); 93 } 94 else 95 { 96 return matchOptional( firstRecord, records, recordIdx ); 97 } 98 } 99 100 private int matchOptional( int firstRecord, List records, int recordIdx ) 101 { 102 if (firstRecord == -1) 103 { 104 return recordIdx; 105 } 106 107 return matchOneOrMany( records, firstRecord ); 108 } 110 111 private int matchRequired( int firstRecord, List records, int recordIdx ) 112 { 113 if (firstRecord == -1) 114 { 115 fail("Manditory record missing or out of order: " + record); 116 } 117 118 return matchOneOrMany( records, firstRecord ); 119 } 121 122 private int matchOneOrMany( List records, int recordIdx ) 123 { 124 if (isZeroOrOne()) 125 { 126 if (findFirstRecord(records, getRecord(), recordIdx+1) != -1) 128 fail("More than one record matched for " + getRecord().getName()); 129 } 130 else if (isZeroToMany()) 131 { 132 if (together) 133 { 134 int nextIdx = findFirstRecord(records, record, recordIdx+1); 135 while (nextIdx != -1) 136 { 137 if (nextIdx - 1 != recordIdx) 138 fail("Records are not together " + record.getName()); 139 recordIdx = nextIdx; 140 nextIdx = findFirstRecord(records, record, recordIdx+1); 141 } 142 } 143 } 144 return recordIdx+1; 145 } 146 147 private boolean isZeroToMany() 148 { 149 return occurance == '*' || occurance == 'M'; 150 } 151 152 private boolean isZeroOrOne() 153 { 154 return occurance == '0' || occurance == '1'; 155 } 156 } 157 158 CheckRecord[] workbookRecords = new CheckRecord[] { 159 new CheckRecord(BOFRecord.class, '1'), 160 new CheckRecord(InterfaceHdrRecord.class, '1'), 161 new CheckRecord(MMSRecord.class, '1'), 162 new CheckRecord(InterfaceEndRecord.class, '1'), 163 new CheckRecord(WriteAccessRecord.class, '1'), 164 new CheckRecord(CodepageRecord.class, '1'), 165 new CheckRecord(DSFRecord.class, '1'), 166 new CheckRecord(TabIdRecord.class, '1'), 167 new CheckRecord(FnGroupCountRecord.class, '1'), 168 new CheckRecord(WindowProtectRecord.class, '1'), 169 new CheckRecord(ProtectRecord.class, '1'), 170 new CheckRecord(PasswordRev4Record.class, '1'), 171 new CheckRecord(WindowOneRecord.class, '1'), 172 new CheckRecord(BackupRecord.class, '1'), 173 new CheckRecord(HideObjRecord.class, '1'), 174 new CheckRecord(DateWindow1904Record.class, '1'), 175 new CheckRecord(PrecisionRecord.class, '1'), 176 new CheckRecord(RefreshAllRecord.class, '1'), 177 new CheckRecord(BookBoolRecord.class, '1'), 178 new CheckRecord(FontRecord.class, 'M'), 179 new CheckRecord(FormatRecord.class, 'M'), 180 new CheckRecord(ExtendedFormatRecord.class, 'M'), 181 new CheckRecord(StyleRecord.class, 'M'), 182 new CheckRecord(UseSelFSRecord.class, '1'), 183 new CheckRecord(BoundSheetRecord.class, 'M'), 184 new CheckRecord(CountryRecord.class, '1'), 185 new CheckRecord(SupBookRecord.class, '0'), 186 new CheckRecord(ExternSheetRecord.class, '0'), 187 new CheckRecord(NameRecord.class, '*'), 188 new CheckRecord(SSTRecord.class, '1'), 189 new CheckRecord(ExtSSTRecord.class, '1'), 190 new CheckRecord(EOFRecord.class, '1'), 191 }; 192 193 CheckRecord[] sheetRecords = new CheckRecord[] { 194 new CheckRecord(BOFRecord.class, '1'), 195 new CheckRecord(CalcModeRecord.class, '1'), 196 new CheckRecord(RefModeRecord.class, '1'), 197 new CheckRecord(IterationRecord.class, '1'), 198 new CheckRecord(DeltaRecord.class, '1'), 199 new CheckRecord(SaveRecalcRecord.class, '1'), 200 new CheckRecord(PrintHeadersRecord.class, '1'), 201 new CheckRecord(PrintGridlinesRecord.class, '1'), 202 new CheckRecord(GridsetRecord.class, '1'), 203 new CheckRecord(GutsRecord.class, '1'), 204 new CheckRecord(DefaultRowHeightRecord.class, '1'), 205 new CheckRecord(WSBoolRecord.class, '1'), 206 new CheckRecord(HeaderRecord.class, '1'), 207 new CheckRecord(FooterRecord.class, '1'), 208 new CheckRecord(HCenterRecord.class, '1'), 209 new CheckRecord(VCenterRecord.class, '1'), 210 new CheckRecord(PrintSetupRecord.class, '1'), 211 new CheckRecord(DefaultColWidthRecord.class, '1'), 212 new CheckRecord(DimensionsRecord.class, '1'), 213 new CheckRecord(WindowTwoRecord.class, '1'), 214 new CheckRecord(SelectionRecord.class, '1'), 215 new CheckRecord(EOFRecord.class, '1') 216 }; 217 218 private void checkWorkbookRecords(Workbook workbook) 219 { 220 List records = workbook.getRecords(); 221 assertTrue(records.get(0) instanceof BOFRecord); 222 assertTrue(records.get(records.size() - 1) instanceof EOFRecord); 223 224 checkRecordOrder(records, workbookRecords); 225 } 227 228 private void checkSheetRecords(Sheet sheet) 229 { 230 List records = sheet.getRecords(); 231 assertTrue(records.get(0) instanceof BOFRecord); 232 assertTrue(records.get(records.size() - 1) instanceof EOFRecord); 233 234 checkRecordOrder(records, sheetRecords); 235 } 237 238 public void checkHSSFWorkbook(HSSFWorkbook wb) 239 { 240 checkWorkbookRecords(wb.getWorkbook()); 241 for (int i = 0; i < wb.getNumberOfSheets(); i++) 242 checkSheetRecords(wb.getSheetAt(i).getSheet()); 243 244 } 245 246 276 277 private static int findFirstRecord( List records, Class record, int startIndex ) 278 { 279 for (int i = startIndex; i < records.size(); i++) 280 { 281 if (record.getName().equals(records.get(i).getClass().getName())) 282 return i; 283 } 284 return -1; 285 } 286 287 292 void checkRecordOrder(List records, CheckRecord[] check) 293 { 294 int recordIdx = 0; 295 for ( int checkIdx = 0; checkIdx < check.length; checkIdx++ ) 296 { 297 recordIdx = check[checkIdx].match(records, recordIdx); 298 } 299 } 300 301 340 341 } 342 | Popular Tags |