KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hssf > dev > BiffViewer


1 /* ====================================================================
2    Copyright 2002-2004 Apache Software Foundation
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8        http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 ==================================================================== */

16
17 /*
18  * BiffViewer.java
19  *
20  * Created on November 13, 2001, 9:23 AM
21  */

22 package org.apache.poi.hssf.dev;
23
24 import org.apache.poi.hssf.record.*;
25 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
26 import org.apache.poi.util.HexDump;
27 import org.apache.poi.util.LittleEndian;
28
29 import java.io.FileInputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31 import java.io.InputStream JavaDoc;
32 import java.util.ArrayList JavaDoc;
33
34 /**
35  * Utillity for reading in BIFF8 records and displaying data from them.
36  *
37  *@author Andrew C. Oliver (acoliver at apache dot org)
38  *@author Glen Stampoultzis (glens at apache.org)
39  *@see #main
40  */

41
42 public class BiffViewer {
43     String JavaDoc filename;
44     private boolean dump;
45
46
47     /**
48      * Creates new BiffViewer
49      *
50      *@param args
51      */

52
53     public BiffViewer(String JavaDoc[] args) {
54         if (args.length > 0) {
55             filename = args[0];
56         } else {
57             System.out.println("BIFFVIEWER REQUIRES A FILENAME***");
58         }
59     }
60
61
62     /**
63      * Method run starts up BiffViewer...
64      */

65
66     public void run() {
67         try {
68             POIFSFileSystem fs =
69                     new POIFSFileSystem(new FileInputStream JavaDoc(filename));
70             InputStream JavaDoc stream =
71                     fs.createDocumentInputStream("Workbook");
72             createRecords(stream, dump);
73         } catch (Exception JavaDoc e) {
74             e.printStackTrace();
75         }
76     }
77
78
79     /**
80      * Create an array of records from an input stream
81      *
82      *@param in the InputStream from which the records
83      * will be obtained
84      *@param dump
85      *@return an array of Records created from the
86      * InputStream
87      *@exception RecordFormatException on error processing the InputStream
88      */

89
90     public static Record[] createRecords(InputStream JavaDoc in, boolean dump)
91              throws RecordFormatException {
92         ArrayList JavaDoc records = new ArrayList JavaDoc();
93 // Record last_record = null;
94
int loc = 0;
95
96         RecordDetails activeRecord = null;
97
98         try {
99 // long offset = 0;
100
short rectype = 0;
101
102             do {
103                 rectype = LittleEndian.readShort(in);
104                 int startloc = loc;
105                 loc += 2;
106                 if (rectype != 0) {
107                     short recsize = LittleEndian.readShort(in);
108
109                     loc += 2;
110                     byte[] data = new byte[(int) recsize];
111
112                     in.read(data);
113                     loc += recsize;
114                     Record record = createRecord(rectype, recsize, data );
115                     if (record.getSid() != ContinueRecord.sid)
116                     {
117                         records.add(record);
118                         if (activeRecord != null)
119                             activeRecord.dump();
120                         activeRecord = new RecordDetails(rectype, recsize, startloc, data, record);
121                     }
122                     else
123                     {
124                         activeRecord.getRecord().processContinueRecord(data);
125                     }
126                     if (dump) {
127                         dumpRaw(rectype, recsize, data);
128                     }
129                 }
130             } while (rectype != 0);
131
132             activeRecord.dump();
133
134         } catch (IOException JavaDoc e) {
135             throw new RecordFormatException("Error reading bytes");
136         }
137         Record[] retval = new Record[records.size()];
138
139         retval = (Record[]) records.toArray(retval);
140         return retval;
141     }
142
143     private static void dumpNormal(Record record, int startloc, short rectype, short recsize)
144     {
145         System.out.println("Offset 0x" + Integer.toHexString(startloc) + " (" + startloc + ")");
146         System.out.println( "recordid = 0x" + Integer.toHexString( rectype ) + ", size = " + recsize );
147         System.out.println( record.toString() );
148
149     }
150
151     private static void dumpContinueRecord(Record last_record, boolean dump, byte[] data) throws IOException JavaDoc {
152         if (last_record == null) {
153             throw new RecordFormatException(
154                     "First record is a ContinueRecord??");
155         }
156         if (dump) {
157             System.out.println(
158                     "-----PRECONTINUED LAST RECORD WOULD SERIALIZE LIKE:");
159             byte[] lr = last_record.serialize();
160
161             if (lr != null) {
162                 HexDump.dump(last_record.serialize(),
163                         0, System.out, 0);
164             }
165             System.out.println();
166             System.out.println(
167                     "-----PRECONTINUED----------------------------------");
168         }
169         last_record.processContinueRecord(data);
170         if (dump) {
171             System.out.println(
172                     "-----CONTINUED LAST RECORD WOULD SERIALIZE LIKE:");
173             HexDump.dump(last_record.serialize(), 0,
174                     System.out, 0);
175             System.out.println();
176             System.out.println(
177                     "-----CONTINUED----------------------------------");
178         }
179     }
180
181
182     private static void dumpUnknownRecord(byte[] data) throws IOException JavaDoc {
183         // record hex dump it!
184
System.out.println(
185                 "-----UNKNOWN----------------------------------");
186         if (data.length > 0) {
187             HexDump.dump(data, 0, System.out, 0);
188         } else {
189             System.out.print("**NO RECORD DATA**");
190         }
191         System.out.println();
192         System.out.println(
193                 "-----UNKNOWN----------------------------------");
194     }
195
196
197     private static void dumpRaw( short rectype, short recsize, byte[] data ) throws IOException JavaDoc
198     {
199         // System.out
200
// .println("fixing to recordize the following");
201
System.out.println("============================================");
202         System.out.print( "rectype = 0x"
203                 + Integer.toHexString( rectype ) );
204         System.out.println( ", recsize = 0x"
205                 + Integer.toHexString( recsize ) );
206         System.out.println(
207                 "-BEGIN DUMP---------------------------------" );
208         if ( data.length > 0 )
209         {
210             HexDump.dump( data, 0, System.out, 0 );
211         }
212         else
213         {
214             System.out.println( "**NO RECORD DATA**" );
215         }
216         // System.out.println();
217
System.out.println(
218                 "-END DUMP-----------------------------------" );
219     }
220
221
222     /**
223      * Essentially a duplicate of RecordFactory. Kept seperate as not to screw
224      * up non-debug operations.
225      *
226      */

227     private static Record createRecord( short rectype, short size,
228                                           byte[] data )
229     {
230         Record retval = null;
231
232         switch ( rectype )
233         {
234
235             case ChartRecord.sid:
236                 retval = new ChartRecord( rectype, size, data );
237                 break;
238             case ChartFormatRecord.sid:
239                 retval = new ChartFormatRecord( rectype, size, data );
240                 break;
241             case SeriesRecord.sid:
242                 retval = new SeriesRecord( rectype, size, data );
243                 break;
244             case BeginRecord.sid:
245                 retval = new BeginRecord( rectype, size, data );
246                 break;
247             case EndRecord.sid:
248                 retval = new EndRecord( rectype, size, data );
249                 break;
250             case BOFRecord.sid:
251                 retval = new BOFRecord( rectype, size, data );
252                 break;
253             case InterfaceHdrRecord.sid:
254                 retval = new InterfaceHdrRecord( rectype, size, data );
255                 break;
256             case MMSRecord.sid:
257                 retval = new MMSRecord( rectype, size, data );
258                 break;
259             case InterfaceEndRecord.sid:
260                 retval = new InterfaceEndRecord( rectype, size, data );
261                 break;
262             case WriteAccessRecord.sid:
263                 retval = new WriteAccessRecord( rectype, size, data );
264                 break;
265             case CodepageRecord.sid:
266                 retval = new CodepageRecord( rectype, size, data );
267                 break;
268             case DSFRecord.sid:
269                 retval = new DSFRecord( rectype, size, data );
270                 break;
271             case TabIdRecord.sid:
272                 retval = new TabIdRecord( rectype, size, data );
273                 break;
274             case FnGroupCountRecord.sid:
275                 retval = new FnGroupCountRecord( rectype, size, data );
276                 break;
277             case WindowProtectRecord.sid:
278                 retval = new WindowProtectRecord( rectype, size, data );
279                 break;
280             case ProtectRecord.sid:
281                 retval = new ProtectRecord( rectype, size, data );
282                 break;
283             case PasswordRecord.sid:
284                 retval = new PasswordRecord( rectype, size, data );
285                 break;
286             case ProtectionRev4Record.sid:
287                 retval = new ProtectionRev4Record( rectype, size, data );
288                 break;
289             case PasswordRev4Record.sid:
290                 retval = new PasswordRev4Record( rectype, size, data );
291                 break;
292             case WindowOneRecord.sid:
293                 retval = new WindowOneRecord( rectype, size, data );
294                 break;
295             case BackupRecord.sid:
296                 retval = new BackupRecord( rectype, size, data );
297                 break;
298             case HideObjRecord.sid:
299                 retval = new HideObjRecord( rectype, size, data );
300                 break;
301             case DateWindow1904Record.sid:
302                 retval = new DateWindow1904Record( rectype, size, data );
303                 break;
304             case PrecisionRecord.sid:
305                 retval = new PrecisionRecord( rectype, size, data );
306                 break;
307             case RefreshAllRecord.sid:
308                 retval = new RefreshAllRecord( rectype, size, data );
309                 break;
310             case BookBoolRecord.sid:
311                 retval = new BookBoolRecord( rectype, size, data );
312                 break;
313             case FontRecord.sid:
314                 retval = new FontRecord( rectype, size, data );
315                 break;
316             case FormatRecord.sid:
317                 retval = new FormatRecord( rectype, size, data );
318                 break;
319             case ExtendedFormatRecord.sid:
320                 retval = new ExtendedFormatRecord( rectype, size, data );
321                 break;
322             case StyleRecord.sid:
323                 retval = new StyleRecord( rectype, size, data );
324                 break;
325             case UseSelFSRecord.sid:
326                 retval = new UseSelFSRecord( rectype, size, data );
327                 break;
328             case BoundSheetRecord.sid:
329                 retval = new BoundSheetRecord( rectype, size, data );
330                 break;
331             case CountryRecord.sid:
332                 retval = new CountryRecord( rectype, size, data );
333                 break;
334             case SSTRecord.sid:
335                 retval = new SSTRecord( rectype, size, data );
336                 break;
337             case ExtSSTRecord.sid:
338                 retval = new ExtSSTRecord( rectype, size, data );
339                 break;
340             case EOFRecord.sid:
341                 retval = new EOFRecord( rectype, size, data );
342                 break;
343             case IndexRecord.sid:
344                 retval = new IndexRecord( rectype, size, data );
345                 break;
346             case CalcModeRecord.sid:
347                 retval = new CalcModeRecord( rectype, size, data );
348                 break;
349             case CalcCountRecord.sid:
350                 retval = new CalcCountRecord( rectype, size, data );
351                 break;
352             case RefModeRecord.sid:
353                 retval = new RefModeRecord( rectype, size, data );
354                 break;
355             case IterationRecord.sid:
356                 retval = new IterationRecord( rectype, size, data );
357                 break;
358             case DeltaRecord.sid:
359                 retval = new DeltaRecord( rectype, size, data );
360                 break;
361             case SaveRecalcRecord.sid:
362                 retval = new SaveRecalcRecord( rectype, size, data );
363                 break;
364             case PrintHeadersRecord.sid:
365                 retval = new PrintHeadersRecord( rectype, size, data );
366                 break;
367             case PrintGridlinesRecord.sid:
368                 retval = new PrintGridlinesRecord( rectype, size, data );
369                 break;
370             case GridsetRecord.sid:
371                 retval = new GridsetRecord( rectype, size, data );
372                 break;
373             case DrawingGroupRecord.sid:
374                 retval = new DrawingGroupRecord( rectype, size, data );
375                 break;
376             case DrawingRecordForBiffViewer.sid:
377                 retval = new DrawingRecordForBiffViewer( rectype, size, data );
378                 break;
379             case DrawingSelectionRecord.sid:
380                 retval = new DrawingSelectionRecord( rectype, size, data );
381                 break;
382             case GutsRecord.sid:
383                 retval = new GutsRecord( rectype, size, data );
384                 break;
385             case DefaultRowHeightRecord.sid:
386                 retval = new DefaultRowHeightRecord( rectype, size, data );
387                 break;
388             case WSBoolRecord.sid:
389                 retval = new WSBoolRecord( rectype, size, data );
390                 break;
391             case HeaderRecord.sid:
392                 retval = new HeaderRecord( rectype, size, data );
393                 break;
394             case FooterRecord.sid:
395                 retval = new FooterRecord( rectype, size, data );
396                 break;
397             case HCenterRecord.sid:
398                 retval = new HCenterRecord( rectype, size, data );
399                 break;
400             case VCenterRecord.sid:
401                 retval = new VCenterRecord( rectype, size, data );
402                 break;
403             case PrintSetupRecord.sid:
404                 retval = new PrintSetupRecord( rectype, size, data );
405                 break;
406             case DefaultColWidthRecord.sid:
407                 retval = new DefaultColWidthRecord( rectype, size, data );
408                 break;
409             case DimensionsRecord.sid:
410                 retval = new DimensionsRecord( rectype, size, data );
411                 break;
412             case RowRecord.sid:
413                 retval = new RowRecord( rectype, size, data );
414                 break;
415             case LabelSSTRecord.sid:
416                 retval = new LabelSSTRecord( rectype, size, data );
417                 break;
418             case RKRecord.sid:
419                 retval = new RKRecord( rectype, size, data );
420                 break;
421             case NumberRecord.sid:
422                 retval = new NumberRecord( rectype, size, data );
423                 break;
424             case DBCellRecord.sid:
425                 retval = new DBCellRecord( rectype, size, data );
426                 break;
427             case WindowTwoRecord.sid:
428                 retval = new WindowTwoRecord( rectype, size, data );
429                 break;
430             case SelectionRecord.sid:
431                 retval = new SelectionRecord( rectype, size, data );
432                 break;
433             case ContinueRecord.sid:
434                 retval = new ContinueRecord( rectype, size, data );
435                 break;
436             case LabelRecord.sid:
437                 retval = new LabelRecord( rectype, size, data );
438                 break;
439             case MulRKRecord.sid:
440                 retval = new MulRKRecord( rectype, size, data );
441                 break;
442             case MulBlankRecord.sid:
443                 retval = new MulBlankRecord( rectype, size, data );
444                 break;
445             case BlankRecord.sid:
446                 retval = new BlankRecord( rectype, size, data );
447                 break;
448             case BoolErrRecord.sid:
449                 retval = new BoolErrRecord( rectype, size, data );
450                 break;
451             case ColumnInfoRecord.sid:
452                 retval = new ColumnInfoRecord( rectype, size, data );
453                 break;
454             case MergeCellsRecord.sid:
455                 retval = new MergeCellsRecord( rectype, size, data );
456                 break;
457             case AreaRecord.sid:
458                 retval = new AreaRecord( rectype, size, data );
459                 break;
460             case DataFormatRecord.sid:
461                 retval = new DataFormatRecord( rectype, size, data );
462                 break;
463             case BarRecord.sid:
464                 retval = new BarRecord( rectype, size, data );
465                 break;
466             case DatRecord.sid:
467                 retval = new DatRecord( rectype, size, data );
468                 break;
469             case PlotGrowthRecord.sid:
470                 retval = new PlotGrowthRecord( rectype, size, data );
471                 break;
472             case UnitsRecord.sid:
473                 retval = new UnitsRecord( rectype, size, data );
474                 break;
475             case FrameRecord.sid:
476                 retval = new FrameRecord( rectype, size, data );
477                 break;
478             case ValueRangeRecord.sid:
479                 retval = new ValueRangeRecord( rectype, size, data );
480                 break;
481             case SeriesListRecord.sid:
482                 retval = new SeriesListRecord( rectype, size, data );
483                 break;
484             case FontBasisRecord.sid:
485                 retval = new FontBasisRecord( rectype, size, data );
486                 break;
487             case FontIndexRecord.sid:
488                 retval = new FontIndexRecord( rectype, size, data );
489                 break;
490             case LineFormatRecord.sid:
491                 retval = new LineFormatRecord( rectype, size, data );
492                 break;
493             case AreaFormatRecord.sid:
494                 retval = new AreaFormatRecord( rectype, size, data );
495                 break;
496             case LinkedDataRecord.sid:
497                 retval = new LinkedDataRecord( rectype, size, data );
498                 break;
499             case FormulaRecord.sid:
500                 retval = new FormulaRecord( rectype, size, data );
501                 break;
502             case SheetPropertiesRecord.sid:
503                 retval = new SheetPropertiesRecord( rectype, size, data );
504                 break;
505             case DefaultDataLabelTextPropertiesRecord.sid:
506                 retval = new DefaultDataLabelTextPropertiesRecord( rectype, size, data );
507                 break;
508             case TextRecord.sid:
509                 retval = new TextRecord( rectype, size, data );
510                 break;
511             case AxisParentRecord.sid:
512                 retval = new AxisParentRecord( rectype, size, data );
513                 break;
514             case AxisLineFormatRecord.sid:
515                 retval = new AxisLineFormatRecord( rectype, size, data );
516                 break;
517             case SupBookRecord.sid:
518                 retval = new SupBookRecord( rectype, size, data );
519                 break;
520             case ExternSheetRecord.sid:
521                 retval = new ExternSheetRecord( rectype, size, data );
522                 break;
523             case SCLRecord.sid:
524                 retval = new SCLRecord( rectype, size, data );
525                 break;
526             case SeriesToChartGroupRecord.sid:
527                 retval = new SeriesToChartGroupRecord( rectype, size, data );
528                 break;
529             case AxisUsedRecord.sid:
530                 retval = new AxisUsedRecord( rectype, size, data );
531                 break;
532             case AxisRecord.sid:
533                 retval = new AxisRecord( rectype, size, data );
534                 break;
535             case CategorySeriesAxisRecord.sid:
536                 retval = new CategorySeriesAxisRecord( rectype, size, data );
537                 break;
538             case AxisOptionsRecord.sid:
539                 retval = new AxisOptionsRecord( rectype, size, data );
540                 break;
541             case TickRecord.sid:
542                 retval = new TickRecord( rectype, size, data );
543                 break;
544             case SeriesTextRecord.sid:
545                 retval = new SeriesTextRecord( rectype, size, data );
546                 break;
547             case ObjectLinkRecord.sid:
548                 retval = new ObjectLinkRecord( rectype, size, data );
549                 break;
550             case PlotAreaRecord.sid:
551                 retval = new PlotAreaRecord( rectype, size, data );
552                 break;
553             case SeriesIndexRecord.sid:
554                 retval = new SeriesIndexRecord( rectype, size, data );
555                 break;
556             case LegendRecord.sid:
557                 retval = new LegendRecord( rectype, size, data );
558                 break;
559             case LeftMarginRecord.sid:
560                 retval = new LeftMarginRecord( rectype, size, data );
561                 break;
562             case RightMarginRecord.sid:
563                 retval = new RightMarginRecord( rectype, size, data );
564                 break;
565             case TopMarginRecord.sid:
566                 retval = new TopMarginRecord( rectype, size, data );
567                 break;
568             case BottomMarginRecord.sid:
569                 retval = new BottomMarginRecord( rectype, size, data );
570                 break;
571             case PaletteRecord.sid:
572                 retval = new PaletteRecord( rectype, size, data );
573                 break;
574             case StringRecord.sid:
575                 retval = new StringRecord( rectype, size, data );
576                 break;
577             case NameRecord.sid:
578                 retval = new NameRecord( rectype, size, data );
579                 break;
580             case PaneRecord.sid:
581                 retval = new PaneRecord( rectype, size, data );
582                 break;
583             case SharedFormulaRecord.sid:
584                  retval = new SharedFormulaRecord( rectype, size, data);
585                  break;
586             case ObjRecord.sid:
587                  retval = new ObjRecord( rectype, size, data);
588                  break;
589             case TextObjectRecord.sid:
590                  retval = new TextObjectRecord( rectype, size, data);
591                  break;
592             case HorizontalPageBreakRecord.sid:
593                 retval = new HorizontalPageBreakRecord( rectype, size, data);
594                 break;
595             case VerticalPageBreakRecord.sid:
596                 retval = new VerticalPageBreakRecord( rectype, size, data);
597                 break;
598             default:
599                 retval = new UnknownRecord( rectype, size, data );
600         }
601         return retval;
602     }
603
604
605     /**
606      * Method setDump - hex dump out data or not.
607      *
608      *@param dump
609      */

610
611     public void setDump(boolean dump) {
612         this.dump = dump;
613     }
614
615
616     /**
617      * Method main with 1 argument just run straight biffview against given
618      * file<P>
619      *
620      * with 2 arguments where the second argument is "on" - run biffviewer<P>
621      *
622      * with hex dumps of records <P>
623      *
624      * with 2 arguments where the second argument is "bfd" just run a big fat
625      * hex dump of the file...don't worry about biffviewing it at all
626      * <p>
627      * Define the system property <code>poi.deserialize.escher</code> to turn on
628      * deserialization of escher records.
629      *
630      */

631     public static void main(String JavaDoc[] args) {
632         try {
633             BiffViewer viewer = new BiffViewer(args);
634
635             if ((args.length > 1) && args[1].equals("on")) {
636                 viewer.setDump(true);
637             }
638             if ((args.length > 1) && args[1].equals("bfd")) {
639                 POIFSFileSystem fs =
640                         new POIFSFileSystem(new FileInputStream JavaDoc(args[0]));
641                 InputStream JavaDoc stream =
642                         fs.createDocumentInputStream("Workbook");
643                 int size = stream.available();
644                 byte[] data = new byte[size];
645
646                 stream.read(data);
647                 HexDump.dump(data, 0, System.out, 0);
648             } else {
649                 viewer.run();
650             }
651         } catch (Exception JavaDoc e) {
652             e.printStackTrace();
653         }
654     }
655
656     static class RecordDetails
657     {
658         short rectype, recsize;
659         int startloc;
660         byte[] data;
661         Record record;
662
663         public RecordDetails( short rectype, short recsize, int startloc, byte[] data, Record record )
664         {
665             this.rectype = rectype;
666             this.recsize = recsize;
667             this.startloc = startloc;
668             this.data = data;
669             this.record = record;
670         }
671
672         public short getRectype()
673         {
674             return rectype;
675         }
676
677         public short getRecsize()
678         {
679             return recsize;
680         }
681
682         public byte[] getData()
683         {
684             return data;
685         }
686
687         public Record getRecord()
688         {
689             return record;
690         }
691
692         public void dump() throws IOException JavaDoc
693         {
694             if (record instanceof UnknownRecord)
695                 dumpUnknownRecord(data);
696             else
697                 dumpNormal(record, startloc, rectype, recsize);
698         }
699     }
700
701 }
702
703
Popular Tags