From 0f52d448b0f4a0f74b8270fe333f64c0412df027 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sun, 12 Jul 2015 18:06:34 +0000 Subject: [PATCH] More whitespace / indent updates git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1690497 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hssf/record/CFHeader12Record.java | 48 +- .../poi/hssf/record/CFHeaderRecord.java | 270 +++--- .../apache/poi/hssf/record/RecordFactory.java | 823 +++++++++--------- .../poi/hssf/record/common/FtrHeader.java | 116 +-- 4 files changed, 622 insertions(+), 635 deletions(-) diff --git a/src/java/org/apache/poi/hssf/record/CFHeader12Record.java b/src/java/org/apache/poi/hssf/record/CFHeader12Record.java index 4b0345ed13..22b165af4e 100644 --- a/src/java/org/apache/poi/hssf/record/CFHeader12Record.java +++ b/src/java/org/apache/poi/hssf/record/CFHeader12Record.java @@ -42,34 +42,34 @@ public final class CFHeader12Record extends CFHeaderRecord { futureHeader.setRecordType(sid); } - public CFHeader12Record(RecordInputStream in) - { - futureHeader = new FtrHeader(in); - read(in); - } + public CFHeader12Record(RecordInputStream in) + { + futureHeader = new FtrHeader(in); + read(in); + } - @Override - protected String getRecordName() { + @Override + protected String getRecordName() { return "CFHEADER12"; } - + protected int getDataSize() { - return FtrHeader.getDataSize() + super.getDataSize(); - } - - public void serialize(LittleEndianOutput out) { - futureHeader.serialize(out); - super.serialize(out); - } + return FtrHeader.getDataSize() + super.getDataSize(); + } - public short getSid() { - return sid; - } + public void serialize(LittleEndianOutput out) { + futureHeader.serialize(out); + super.serialize(out); + } - public Object clone() { - CFHeader12Record result = new CFHeader12Record(); - result.futureHeader = (FtrHeader)futureHeader.clone(); - // TODO Clone the rest via the base - return result; - } + public short getSid() { + return sid; + } + + public Object clone() { + CFHeader12Record result = new CFHeader12Record(); + result.futureHeader = (FtrHeader)futureHeader.clone(); + // TODO Clone the rest via the base + return result; + } } diff --git a/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java index 55dd98d50a..6ceba5723e 100644 --- a/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java +++ b/src/java/org/apache/poi/hssf/record/CFHeaderRecord.java @@ -29,143 +29,137 @@ import org.apache.poi.util.LittleEndianOutput; * TODO Move most of the logic into a base class */ public class CFHeaderRecord extends StandardRecord { - public static final short sid = 0x01B0; - - private int field_1_numcf; - private int field_2_need_recalculation_and_id; - private CellRangeAddress field_3_enclosing_cell_range; - private CellRangeAddressList field_4_cell_ranges; - - /** Creates new CFHeaderRecord */ - public CFHeaderRecord() - { - field_4_cell_ranges = new CellRangeAddressList(); - } - public CFHeaderRecord(CellRangeAddress[] regions, int nRules) { - CellRangeAddress[] unmergedRanges = regions; - CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges); - setCellRanges(mergeCellRanges); - field_1_numcf = nRules; - } - - public CFHeaderRecord(RecordInputStream in) { - read(in); - } - protected void read(RecordInputStream in) { - field_1_numcf = in.readShort(); - field_2_need_recalculation_and_id = in.readShort(); - field_3_enclosing_cell_range = new CellRangeAddress(in); - field_4_cell_ranges = new CellRangeAddressList(in); - } - - public int getNumberOfConditionalFormats() { - return field_1_numcf; - } - public void setNumberOfConditionalFormats(int n) { - field_1_numcf=n; - } - - public boolean getNeedRecalculation() { - // Held on the 1st bit - return field_2_need_recalculation_and_id % 2 == 1; - } - public void setNeedRecalculation(boolean b) { - // held on the first bit - if (b == getNeedRecalculation()) return; - if (b) field_2_need_recalculation_and_id++; - else field_2_need_recalculation_and_id--; - } - - public int getID() - { - // Remaining 15 bits of field 2 - return field_2_need_recalculation_and_id>>1; - } - public void setID(int id) - { + public static final short sid = 0x01B0; + + private int field_1_numcf; + private int field_2_need_recalculation_and_id; + private CellRangeAddress field_3_enclosing_cell_range; + private CellRangeAddressList field_4_cell_ranges; + + /** Creates new CFHeaderRecord */ + public CFHeaderRecord() { + field_4_cell_ranges = new CellRangeAddressList(); + } + public CFHeaderRecord(CellRangeAddress[] regions, int nRules) { + CellRangeAddress[] unmergedRanges = regions; + CellRangeAddress[] mergeCellRanges = CellRangeUtil.mergeCellRanges(unmergedRanges); + setCellRanges(mergeCellRanges); + field_1_numcf = nRules; + } + + public CFHeaderRecord(RecordInputStream in) { + read(in); + } + protected void read(RecordInputStream in) { + field_1_numcf = in.readShort(); + field_2_need_recalculation_and_id = in.readShort(); + field_3_enclosing_cell_range = new CellRangeAddress(in); + field_4_cell_ranges = new CellRangeAddressList(in); + } + + public int getNumberOfConditionalFormats() { + return field_1_numcf; + } + public void setNumberOfConditionalFormats(int n) { + field_1_numcf=n; + } + + public boolean getNeedRecalculation() { + // Held on the 1st bit + return field_2_need_recalculation_and_id % 2 == 1; + } + public void setNeedRecalculation(boolean b) { + // held on the first bit + if (b == getNeedRecalculation()) return; + if (b) field_2_need_recalculation_and_id++; + else field_2_need_recalculation_and_id--; + } + + public int getID() { // Remaining 15 bits of field 2 - boolean needsRecalc = getNeedRecalculation(); - field_2_need_recalculation_and_id = (id<<1); - if (needsRecalc) field_2_need_recalculation_and_id++; - } - - public CellRangeAddress getEnclosingCellRange() { - return field_3_enclosing_cell_range; - } - public void setEnclosingCellRange(CellRangeAddress cr) { - field_3_enclosing_cell_range = cr; - } - - /** - * Set cell ranges list to a single cell range and - * modify the enclosing cell range accordingly. - * @param cellRanges - list of CellRange objects - */ - public void setCellRanges(CellRangeAddress[] cellRanges) { - if(cellRanges == null) - { - throw new IllegalArgumentException("cellRanges must not be null"); - } - CellRangeAddressList cral = new CellRangeAddressList(); - CellRangeAddress enclosingRange = null; - for (int i = 0; i < cellRanges.length; i++) - { - CellRangeAddress cr = cellRanges[i]; - enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange); - cral.addCellRangeAddress(cr); - } - field_3_enclosing_cell_range = enclosingRange; - field_4_cell_ranges = cral; - } - - public CellRangeAddress[] getCellRanges() { - return field_4_cell_ranges.getCellRangeAddresses(); - } - - protected String getRecordName() { - return "CFHEADER"; - } - public String toString() { - StringBuffer buffer = new StringBuffer(); - - buffer.append("[").append(getRecordName()).append("]\n"); - buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n"); - buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n"); - buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n"); - buffer.append(" .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n"); - buffer.append(" .cfranges=["); - for( int i=0; i>1; + } + public void setID(int id) { + // Remaining 15 bits of field 2 + boolean needsRecalc = getNeedRecalculation(); + field_2_need_recalculation_and_id = (id<<1); + if (needsRecalc) field_2_need_recalculation_and_id++; + } + + public CellRangeAddress getEnclosingCellRange() { + return field_3_enclosing_cell_range; + } + public void setEnclosingCellRange(CellRangeAddress cr) { + field_3_enclosing_cell_range = cr; + } + + /** + * Set cell ranges list to a single cell range and + * modify the enclosing cell range accordingly. + * @param cellRanges - list of CellRange objects + */ + public void setCellRanges(CellRangeAddress[] cellRanges) { + if(cellRanges == null) { + throw new IllegalArgumentException("cellRanges must not be null"); + } + CellRangeAddressList cral = new CellRangeAddressList(); + CellRangeAddress enclosingRange = null; + for (int i = 0; i < cellRanges.length; i++) { + CellRangeAddress cr = cellRanges[i]; + enclosingRange = CellRangeUtil.createEnclosingCellRange(cr, enclosingRange); + cral.addCellRangeAddress(cr); + } + field_3_enclosing_cell_range = enclosingRange; + field_4_cell_ranges = cral; + } + + public CellRangeAddress[] getCellRanges() { + return field_4_cell_ranges.getCellRangeAddresses(); + } + + protected String getRecordName() { + return "CFHEADER"; + } + public String toString() { + StringBuffer buffer = new StringBuffer(); + + buffer.append("[").append(getRecordName()).append("]\n"); + buffer.append(" .id = ").append(Integer.toHexString(sid)).append("\n"); + buffer.append(" .numCF = ").append(getNumberOfConditionalFormats()).append("\n"); + buffer.append(" .needRecalc = ").append(getNeedRecalculation()).append("\n"); + buffer.append(" .enclosingCellRange= ").append(getEnclosingCellRange()).append("\n"); + buffer.append(" .cfranges=["); + for( int i=0; i * * @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; - - private interface I_RecordCreator { - Record create(RecordInputStream in); - - Class getRecordClass(); - } - private static final class ReflectionConstructorRecordCreator implements I_RecordCreator { - - private final Constructor _c; - public ReflectionConstructorRecordCreator(Constructor c) { - _c = c; - } - public Record create(RecordInputStream in) { - Object[] args = { in, }; - try { - return _c.newInstance(args); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - if (t instanceof RecordFormatException) { - throw (RecordFormatException)t; - } else if (t instanceof EncryptedDocumentException) { - throw (EncryptedDocumentException)t; - } else { - throw new RecordFormatException("Unable to construct record instance" , t); - } - } - } - public Class getRecordClass() { - return _c.getDeclaringClass(); - } - } - /** - * A "create" method is used instead of the usual constructor if the created record might - * be of a different class to the declaring class. - */ - private static final class ReflectionMethodRecordCreator implements I_RecordCreator { - - private final Method _m; - public ReflectionMethodRecordCreator(Method m) { - _m = m; - } - public Record create(RecordInputStream in) { - Object[] args = { in, }; - try { - return (Record) _m.invoke(null, args); - } catch (IllegalArgumentException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RecordFormatException("Unable to construct record instance" , e.getTargetException()); - } - } - @SuppressWarnings("unchecked") - public Class getRecordClass() { - return (Class) _m.getDeclaringClass(); - } - } - - - private static final Class[] CONSTRUCTOR_ARGS = { RecordInputStream.class, }; - - /** - * contains the classes for all the records we want to parse.
- * Note - this most but not *every* subclass of Record. - */ - @SuppressWarnings("unchecked") - private static final Class[] recordClasses = new Class[] { - ArrayRecord.class, + private static final int NUM_RECORDS = 512; + + private interface I_RecordCreator { + Record create(RecordInputStream in); + + Class getRecordClass(); + } + private static final class ReflectionConstructorRecordCreator implements I_RecordCreator { + + private final Constructor _c; + public ReflectionConstructorRecordCreator(Constructor c) { + _c = c; + } + public Record create(RecordInputStream in) { + Object[] args = { in, }; + try { + return _c.newInstance(args); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + Throwable t = e.getTargetException(); + if (t instanceof RecordFormatException) { + throw (RecordFormatException)t; + } else if (t instanceof EncryptedDocumentException) { + throw (EncryptedDocumentException)t; + } else { + throw new RecordFormatException("Unable to construct record instance" , t); + } + } + } + public Class getRecordClass() { + return _c.getDeclaringClass(); + } + } + /** + * A "create" method is used instead of the usual constructor if the created record might + * be of a different class to the declaring class. + */ + private static final class ReflectionMethodRecordCreator implements I_RecordCreator { + private final Method _m; + public ReflectionMethodRecordCreator(Method m) { + _m = m; + } + public Record create(RecordInputStream in) { + Object[] args = { in, }; + try { + return (Record) _m.invoke(null, args); + } catch (IllegalArgumentException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RecordFormatException("Unable to construct record instance" , e.getTargetException()); + } + } + @SuppressWarnings("unchecked") + public Class getRecordClass() { + return (Class) _m.getDeclaringClass(); + } + } + + private static final Class[] CONSTRUCTOR_ARGS = { RecordInputStream.class, }; + + /** + * contains the classes for all the records we want to parse.
+ * Note - this most but not *every* subclass of Record. + */ + @SuppressWarnings("unchecked") + private static final Class[] recordClasses = new Class[] { + ArrayRecord.class, AutoFilterInfoRecord.class, BackupRecord.class, - BlankRecord.class, - BOFRecord.class, - BookBoolRecord.class, - BoolErrRecord.class, - BottomMarginRecord.class, - BoundSheetRecord.class, - CalcCountRecord.class, - CalcModeRecord.class, - CFHeaderRecord.class, + BlankRecord.class, + BOFRecord.class, + BookBoolRecord.class, + BoolErrRecord.class, + BottomMarginRecord.class, + BoundSheetRecord.class, + CalcCountRecord.class, + CalcModeRecord.class, + CFHeaderRecord.class, CFHeader12Record.class, - CFRuleRecord.class, - ChartRecord.class, - ChartTitleFormatRecord.class, - CodepageRecord.class, - ColumnInfoRecord.class, - ContinueRecord.class, - CountryRecord.class, - CRNCountRecord.class, - CRNRecord.class, - DateWindow1904Record.class, - DBCellRecord.class, + CFRuleRecord.class, + ChartRecord.class, + ChartTitleFormatRecord.class, + CodepageRecord.class, + ColumnInfoRecord.class, + ContinueRecord.class, + CountryRecord.class, + CRNCountRecord.class, + CRNRecord.class, + DateWindow1904Record.class, + DBCellRecord.class, DConRefRecord.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, - FeatRecord.class, - FeatHdrRecord.class, - FilePassRecord.class, - FileSharingRecord.class, - FnGroupCountRecord.class, - FontRecord.class, - FooterRecord.class, - FormatRecord.class, - FormulaRecord.class, - GridsetRecord.class, - GutsRecord.class, - HCenterRecord.class, - HeaderRecord.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, + FeatRecord.class, + FeatHdrRecord.class, + FilePassRecord.class, + FileSharingRecord.class, + FnGroupCountRecord.class, + FontRecord.class, + FooterRecord.class, + FormatRecord.class, + FormulaRecord.class, + GridsetRecord.class, + GutsRecord.class, + HCenterRecord.class, + HeaderRecord.class, HeaderFooterRecord.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, - NameCommentRecord.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, - TableStylesRecord.class, - TextObjectRecord.class, - TopMarginRecord.class, - UncalcedRecord.class, - UseSelFSRecord.class, - UserSViewBegin.class, - UserSViewEnd.class, - ValueRangeRecord.class, - VCenterRecord.class, - VerticalPageBreakRecord.class, - WindowOneRecord.class, - WindowProtectRecord.class, - WindowTwoRecord.class, - WriteAccessRecord.class, - WriteProtectRecord.class, - WSBoolRecord.class, - - // chart records - BeginRecord.class, - ChartFRTInfoRecord.class, - ChartStartBlockRecord.class, - ChartEndBlockRecord.class, -// TODO ChartFormatRecord.class, - ChartStartObjectRecord.class, - ChartEndObjectRecord.class, - CatLabRecord.class, - DataFormatRecord.class, - EndRecord.class, - LinkedDataRecord.class, - SeriesToChartGroupRecord.class, - - // pivot table records - DataItemRecord.class, - ExtendedPivotTableViewFieldsRecord.class, - PageItemRecord.class, - StreamIDRecord.class, - ViewDefinitionRecord.class, - ViewFieldsRecord.class, - ViewSourceRecord.class, - }; - - /** - * cache of the recordsToMap(); - */ - private static final Map _recordCreatorsById = recordsToMap(recordClasses); - - private static short[] _allKnownRecordSIDs; - - /** - * Debug / diagnosis method
- * Gets the POI implementation class for a given sid. Only a subset of the any BIFF - * records are actually interpreted by POI. A few others are known but not interpreted - * (see {@link UnknownRecord#getBiffName(int)}). - * @return the POI implementation class for the specified record sid. - * null if the specified record is not interpreted by POI. - */ - public static Class getRecordClass(int sid) { - I_RecordCreator rc = _recordCreatorsById.get(Integer.valueOf(sid)); - if (rc == null) { - return null; - } - return rc.getRecordClass(); - } - /** - * 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 record = createSingleRecord(in); - if (record instanceof DBCellRecord) { - // Not needed by POI. Regenerated from scratch by POI when spreadsheet is written - return new Record[] { null, }; - } - if (record instanceof RKRecord) { - return new Record[] { convertToNumberRecord((RKRecord) record), }; - } - if (record instanceof MulRKRecord) { - return convertRKRecords((MulRKRecord)record); - } - return new Record[] { record, }; - } - - public static Record createSingleRecord(RecordInputStream in) { - I_RecordCreator constructor = _recordCreatorsById.get(Integer.valueOf(in.getSid())); - - if (constructor == null) { - return new UnknownRecord(in); - } - - return constructor.create(in); - } - - /** - * RK record is a slightly smaller alternative to NumberRecord - * POI likes NumberRecord better - */ - public static NumberRecord convertToNumberRecord(RKRecord rk) { - NumberRecord num = new NumberRecord(); - - num.setColumn(rk.getColumn()); - num.setRow(rk.getRow()); - num.setXFIndex(rk.getXFIndex()); - num.setValue(rk.getRKNumber()); - return num; - } - - /** - * Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s - */ - public static NumberRecord[] convertRKRecords(MulRKRecord mrk) { - NumberRecord[] mulRecs = new NumberRecord[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)); - mulRecs[k] = nr; - } - return mulRecs; - } - - /** - * Converts a {@link MulBlankRecord} into an equivalent array of {@link BlankRecord}s - */ - public static BlankRecord[] convertBlankRecords(MulBlankRecord mbk) { - BlankRecord[] mulRecs = new BlankRecord[mbk.getNumColumns()]; - for (int k = 0; k < mbk.getNumColumns(); k++) { - BlankRecord br = new BlankRecord(); - - br.setColumn((short) (k + mbk.getFirstColumn())); - br.setRow(mbk.getRow()); - br.setXFIndex(mbk.getXFAt(k)); - mulRecs[k] = br; - } - return mulRecs; - } - - /** - * @return an array of all the SIDS for all known records - */ - public static short[] getAllKnownRecordSIDs() { - if (_allKnownRecordSIDs == null) { - short[] results = new short[ _recordCreatorsById.size() ]; - int i = 0; - - for (Iterator iterator = _recordCreatorsById.keySet().iterator(); iterator.hasNext(); ) { - Integer sid = iterator.next(); - - results[i++] = sid.shortValue(); - } - Arrays.sort(results); - _allKnownRecordSIDs = results; - } - - return _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 ]; - if(!Record.class.isAssignableFrom(recClass)) { - throw new RuntimeException("Invalid record sub-class (" + recClass.getName() + ")"); - } - if(Modifier.isAbstract(recClass.getModifiers())) { - throw new RuntimeException("Invalid record class (" + recClass.getName() + ") - must not be abstract"); - } - if(!uniqueRecClasses.add(recClass)) { - throw new RuntimeException("duplicate record class (" + recClass.getName() + ")"); - } - - int sid; - try { - sid = recClass.getField("sid").getShort(null); - } catch (Exception illegalArgumentException) { - throw new RecordFormatException( - "Unable to determine record types"); - } - Integer key = Integer.valueOf(sid); - if (result.containsKey(key)) { - Class prevClass = result.get(key).getRecordClass(); - throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase() - + " for classes (" + recClass.getName() + ") and (" + prevClass.getName() + ")"); - } - result.put(key, getRecordCreator(recClass)); - } -// result.put(Integer.valueOf(0x0406), result.get(Integer.valueOf(0x06))); - return result; - } - - private static I_RecordCreator getRecordCreator(Class recClass) { - try { - Constructor constructor; - constructor = recClass.getConstructor(CONSTRUCTOR_ARGS); - return new ReflectionConstructorRecordCreator(constructor); - } catch (NoSuchMethodException e) { - // fall through and look for other construction methods - } - try { - Method m = recClass.getDeclaredMethod("create", CONSTRUCTOR_ARGS); - return new ReflectionMethodRecordCreator(m); - } catch (NoSuchMethodException e) { - throw new RuntimeException("Failed to find constructor or create method for (" + recClass.getName() + ")."); - } - } - /** - * 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); - - RecordFactoryInputStream recStream = new RecordFactoryInputStream(in, true); - - Record record; - while ((record = recStream.nextRecord())!=null) { - records.add(record); - } - - return records; - } + 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, + NameCommentRecord.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, + TableStylesRecord.class, + TextObjectRecord.class, + TopMarginRecord.class, + UncalcedRecord.class, + UseSelFSRecord.class, + UserSViewBegin.class, + UserSViewEnd.class, + ValueRangeRecord.class, + VCenterRecord.class, + VerticalPageBreakRecord.class, + WindowOneRecord.class, + WindowProtectRecord.class, + WindowTwoRecord.class, + WriteAccessRecord.class, + WriteProtectRecord.class, + WSBoolRecord.class, + + // chart records + BeginRecord.class, + ChartFRTInfoRecord.class, + ChartStartBlockRecord.class, + ChartEndBlockRecord.class, + // TODO ChartFormatRecord.class, + ChartStartObjectRecord.class, + ChartEndObjectRecord.class, + CatLabRecord.class, + DataFormatRecord.class, + EndRecord.class, + LinkedDataRecord.class, + SeriesToChartGroupRecord.class, + + // pivot table records + DataItemRecord.class, + ExtendedPivotTableViewFieldsRecord.class, + PageItemRecord.class, + StreamIDRecord.class, + ViewDefinitionRecord.class, + ViewFieldsRecord.class, + ViewSourceRecord.class, + }; + + /** + * cache of the recordsToMap(); + */ + private static final Map _recordCreatorsById = recordsToMap(recordClasses); + + private static short[] _allKnownRecordSIDs; + + /** + * Debug / diagnosis method
+ * Gets the POI implementation class for a given sid. Only a subset of the any BIFF + * records are actually interpreted by POI. A few others are known but not interpreted + * (see {@link UnknownRecord#getBiffName(int)}). + * @return the POI implementation class for the specified record sid. + * null if the specified record is not interpreted by POI. + */ + public static Class getRecordClass(int sid) { + I_RecordCreator rc = _recordCreatorsById.get(Integer.valueOf(sid)); + if (rc == null) { + return null; + } + return rc.getRecordClass(); + } + /** + * 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 record = createSingleRecord(in); + if (record instanceof DBCellRecord) { + // Not needed by POI. Regenerated from scratch by POI when spreadsheet is written + return new Record[] { null, }; + } + if (record instanceof RKRecord) { + return new Record[] { convertToNumberRecord((RKRecord) record), }; + } + if (record instanceof MulRKRecord) { + return convertRKRecords((MulRKRecord)record); + } + return new Record[] { record, }; + } + + public static Record createSingleRecord(RecordInputStream in) { + I_RecordCreator constructor = _recordCreatorsById.get(Integer.valueOf(in.getSid())); + + if (constructor == null) { + return new UnknownRecord(in); + } + + return constructor.create(in); + } + + /** + * RK record is a slightly smaller alternative to NumberRecord + * POI likes NumberRecord better + */ + public static NumberRecord convertToNumberRecord(RKRecord rk) { + NumberRecord num = new NumberRecord(); + + num.setColumn(rk.getColumn()); + num.setRow(rk.getRow()); + num.setXFIndex(rk.getXFIndex()); + num.setValue(rk.getRKNumber()); + return num; + } + + /** + * Converts a {@link MulRKRecord} into an equivalent array of {@link NumberRecord}s + */ + public static NumberRecord[] convertRKRecords(MulRKRecord mrk) { + NumberRecord[] mulRecs = new NumberRecord[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)); + mulRecs[k] = nr; + } + return mulRecs; + } + + /** + * Converts a {@link MulBlankRecord} into an equivalent array of {@link BlankRecord}s + */ + public static BlankRecord[] convertBlankRecords(MulBlankRecord mbk) { + BlankRecord[] mulRecs = new BlankRecord[mbk.getNumColumns()]; + for (int k = 0; k < mbk.getNumColumns(); k++) { + BlankRecord br = new BlankRecord(); + + br.setColumn((short) (k + mbk.getFirstColumn())); + br.setRow(mbk.getRow()); + br.setXFIndex(mbk.getXFAt(k)); + mulRecs[k] = br; + } + return mulRecs; + } + + /** + * @return an array of all the SIDS for all known records + */ + public static short[] getAllKnownRecordSIDs() { + if (_allKnownRecordSIDs == null) { + short[] results = new short[ _recordCreatorsById.size() ]; + int i = 0; + + for (Iterator iterator = _recordCreatorsById.keySet().iterator(); iterator.hasNext(); ) { + Integer sid = iterator.next(); + + results[i++] = sid.shortValue(); + } + Arrays.sort(results); + _allKnownRecordSIDs = results; + } + + return _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 ]; + if(!Record.class.isAssignableFrom(recClass)) { + throw new RuntimeException("Invalid record sub-class (" + recClass.getName() + ")"); + } + if(Modifier.isAbstract(recClass.getModifiers())) { + throw new RuntimeException("Invalid record class (" + recClass.getName() + ") - must not be abstract"); + } + if(!uniqueRecClasses.add(recClass)) { + throw new RuntimeException("duplicate record class (" + recClass.getName() + ")"); + } + + int sid; + try { + sid = recClass.getField("sid").getShort(null); + } catch (Exception illegalArgumentException) { + throw new RecordFormatException( + "Unable to determine record types"); + } + Integer key = Integer.valueOf(sid); + if (result.containsKey(key)) { + Class prevClass = result.get(key).getRecordClass(); + throw new RuntimeException("duplicate record sid 0x" + Integer.toHexString(sid).toUpperCase() + + " for classes (" + recClass.getName() + ") and (" + prevClass.getName() + ")"); + } + result.put(key, getRecordCreator(recClass)); + } + // result.put(Integer.valueOf(0x0406), result.get(Integer.valueOf(0x06))); + return result; + } + + private static I_RecordCreator getRecordCreator(Class recClass) { + try { + Constructor constructor; + constructor = recClass.getConstructor(CONSTRUCTOR_ARGS); + return new ReflectionConstructorRecordCreator(constructor); + } catch (NoSuchMethodException e) { + // fall through and look for other construction methods + } + try { + Method m = recClass.getDeclaredMethod("create", CONSTRUCTOR_ARGS); + return new ReflectionMethodRecordCreator(m); + } catch (NoSuchMethodException e) { + throw new RuntimeException("Failed to find constructor or create method for (" + recClass.getName() + ")."); + } + } + /** + * 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); + + RecordFactoryInputStream recStream = new RecordFactoryInputStream(in, true); + + Record record; + while ((record = recStream.nextRecord())!=null) { + records.add(record); + } + + return records; + } } diff --git a/src/java/org/apache/poi/hssf/record/common/FtrHeader.java b/src/java/org/apache/poi/hssf/record/common/FtrHeader.java index b240e8112f..1df69cfcb9 100644 --- a/src/java/org/apache/poi/hssf/record/common/FtrHeader.java +++ b/src/java/org/apache/poi/hssf/record/common/FtrHeader.java @@ -28,70 +28,70 @@ import org.apache.poi.util.LittleEndianOutput; * beyond those of a traditional record. */ public final class FtrHeader { - /** This MUST match the type on the containing record */ - private short recordType; - /** This is a FrtFlags */ - private short grbitFrt; - /** MUST be 8 bytes and all zero TODO Correct this! */ - private byte[] reserved; + /** This MUST match the type on the containing record */ + private short recordType; + /** This is a FrtFlags */ + private short grbitFrt; + /** MUST be 8 bytes and all zero TODO Correct this! */ + private byte[] reserved; - public FtrHeader() { - reserved = new byte[8]; - } + public FtrHeader() { + reserved = new byte[8]; + } - public FtrHeader(RecordInputStream in) { - recordType = in.readShort(); - grbitFrt = in.readShort(); - - reserved = new byte[8]; - in.read(reserved, 0, 8); - } + public FtrHeader(RecordInputStream in) { + recordType = in.readShort(); + grbitFrt = in.readShort(); - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append(" [FUTURE HEADER]\n"); - buffer.append(" Type " + recordType); - buffer.append(" Flags " + grbitFrt); - buffer.append(" [/FUTURE HEADER]\n"); - return buffer.toString(); - } + reserved = new byte[8]; + in.read(reserved, 0, 8); + } - public void serialize(LittleEndianOutput out) { - out.writeShort(recordType); - out.writeShort(grbitFrt); - out.write(reserved); - } + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append(" [FUTURE HEADER]\n"); + buffer.append(" Type " + recordType); + buffer.append(" Flags " + grbitFrt); + buffer.append(" [/FUTURE HEADER]\n"); + return buffer.toString(); + } - public static int getDataSize() { - return 12; - } + public void serialize(LittleEndianOutput out) { + out.writeShort(recordType); + out.writeShort(grbitFrt); + out.write(reserved); + } - public short getRecordType() { - return recordType; - } - public void setRecordType(short recordType) { - this.recordType = recordType; - } + public static int getDataSize() { + return 12; + } - public short getGrbitFrt() { - return grbitFrt; - } - public void setGrbitFrt(short grbitFrt) { - this.grbitFrt = grbitFrt; - } + public short getRecordType() { + return recordType; + } + public void setRecordType(short recordType) { + this.recordType = recordType; + } - public byte[] getReserved() { - return reserved; - } - public void setReserved(byte[] reserved) { - this.reserved = reserved; - } - - public Object clone() { - FtrHeader result = new FtrHeader(); - result.recordType = recordType; - result.grbitFrt = grbitFrt; - result.reserved = reserved; - return result; - } + public short getGrbitFrt() { + return grbitFrt; + } + public void setGrbitFrt(short grbitFrt) { + this.grbitFrt = grbitFrt; + } + + public byte[] getReserved() { + return reserved; + } + public void setReserved(byte[] reserved) { + this.reserved = reserved; + } + + public Object clone() { + FtrHeader result = new FtrHeader(); + result.recordType = recordType; + result.grbitFrt = grbitFrt; + result.reserved = reserved; + return result; + } } \ No newline at end of file -- 2.39.5