KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hssf > record > aggregates > ValueRecordsAggregate


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

32
33
34
35
36
37 package org.apache.poi.hssf.record.aggregates;
38
39
40
41 import org.apache.poi.hssf.record.*;
42
43
44
45 import java.util.Iterator JavaDoc;
46
47 import java.util.List JavaDoc;
48
49 import java.util.SortedMap JavaDoc;
50
51 import java.util.TreeMap JavaDoc;
52
53
54
55
56
57 /**
58
59  *
60
61  * Aggregate value records together. Things are easier to handle that way.
62
63  *
64
65  * @author andy
66
67  * @author Glen Stampoultzis (glens at apache.org)
68
69  * @author Jason Height (jheight at chariot dot net dot au)
70
71  */

72
73
74
75 public class ValueRecordsAggregate
76
77     extends Record
78
79 {
80
81     public final static short sid = -1000;
82
83     int firstcell = -1;
84
85     int lastcell = -1;
86
87     TreeMap JavaDoc records = null;
88
89
90
91    /** This class is used to find a row in the TreeMap.
92
93     *
94
95     * This instance of which is used by the rowHasCells method as the key.
96
97     */

98
99    private class RowComparator implements CellValueRecordInterface, Comparable JavaDoc {
100
101      private int row;
102
103      
104
105      public void setRow(int row) {
106
107        this.row = row;
108
109      }
110
111      
112
113      public int compareTo(Object JavaDoc obj) {
114
115          CellValueRecordInterface cell = (CellValueRecordInterface) obj;
116
117  
118
119          if (row == cell.getRow()) {
120
121            return 0;
122
123          }
124
125          else if (row < cell.getRow()) {
126
127            return -1;
128
129          }
130
131          else if (row > cell.getRow()){
132
133            return 1;
134
135          }
136
137          return -1;
138
139      }
140
141      public int getRow() { return row;}
142
143      public short getColumn() { return 0;}
144
145      public void setColumn(short col){}
146
147      public void setXFIndex(short xf){}
148
149      public short getXFIndex(){return 0;}
150
151      public boolean isBefore(CellValueRecordInterface i){ return false; }
152
153      public boolean isAfter(CellValueRecordInterface i){ return false; }
154
155      public boolean isEqual(CellValueRecordInterface i){ return false; }
156
157      public Object JavaDoc clone(){ return null;}
158
159    }
160
161    
162
163    /**
164
165     * Iterates the cell records that exist between the startRow and endRow (inclusive).
166
167     *
168
169     * User must ensure that hasNext & next are called insequence for correct
170
171     * operation. Could fix, but since this is only used internally to the
172
173     * ValueRecordsAggregate class there doesnt seem much point.
174
175     */

176
177    private class RowCellIterator implements Iterator JavaDoc {
178
179      private int startRow;
180
181      private int endRow;
182
183      private Iterator JavaDoc internalIterator;
184
185      private CellValueRecordInterface atCell;
186
187      
188
189      public class RowCellComparator extends RowComparator {
190
191        public int compareTo(Object JavaDoc obj) {
192
193            CellValueRecordInterface cell = (CellValueRecordInterface) obj;
194
195   
196
197            if (getRow() == cell.getRow() && cell.getColumn() == 0) {
198
199              return 0;
200
201            }
202
203            else if (getRow() < cell.getRow()) {
204
205              return -1;
206
207            }
208
209            else if (getRow() > cell.getRow()){
210
211              return 1;
212
213            }
214
215            if (cell.getColumn() > 0)
216
217            {
218
219                return -1;
220
221            }
222
223            if (cell.getColumn() < 0)
224
225            {
226
227                return 1;
228
229            }
230
231            return -1;
232
233        }
234
235      }
236
237      
238
239      private RowCellComparator rowCellCompare;
240
241      
242
243      
244
245      public RowCellIterator(int startRow, int endRow) {
246
247        this.startRow = startRow;
248
249        this.endRow = endRow;
250
251        rowCellCompare = new RowCellComparator();
252
253        rowCellCompare.setRow(startRow);
254
255      }
256
257      
258
259      public boolean hasNext() {
260
261        if (internalIterator == null) {
262
263          internalIterator = records.tailMap(rowCellCompare).values().iterator();
264
265        }
266
267        if (internalIterator.hasNext()) {
268
269          atCell = (CellValueRecordInterface) internalIterator.next();
270
271          return (atCell.getRow() <= endRow);
272
273        } else return false;
274
275      }
276
277      
278
279      public Object JavaDoc next() {
280
281        return atCell;
282
283      }
284
285      
286
287      public void remove() {
288
289        //Do Nothing (Not called)
290

291      }
292
293    }
294
295    
296
297    //Only need a single instance of this class, but the row fields
298

299    //will probably change each use. Instance is only used in the rowHasCells method.
300

301    public final RowComparator compareRow = new RowComparator();
302
303    
304
305     /** Creates a new instance of ValueRecordsAggregate */
306
307
308
309     public ValueRecordsAggregate()
310
311     {
312
313         records = new TreeMap JavaDoc();
314
315     }
316
317
318
319     public void insertCell(CellValueRecordInterface cell)
320
321     {
322
323         Object JavaDoc o = records.put(cell, cell);
324
325
326
327         if ((cell.getColumn() < firstcell) || (firstcell == -1))
328
329         {
330
331             firstcell = cell.getColumn();
332
333         }
334
335         if ((cell.getColumn() > lastcell) || (lastcell == -1))
336
337         {
338
339             lastcell = cell.getColumn();
340
341         }
342
343     }
344
345
346
347     public void removeCell(CellValueRecordInterface cell)
348
349     {
350
351         records.remove(cell);
352
353     }
354
355
356
357     public int getPhysicalNumberOfCells()
358
359     {
360
361         return records.size();
362
363     }
364
365
366
367     public int getFirstCellNum()
368
369     {
370
371         return firstcell;
372
373     }
374
375
376
377     public int getLastCellNum()
378
379     {
380
381         return lastcell;
382
383     }
384
385
386
387     public int construct(int offset, List JavaDoc records)
388
389     {
390
391         int k = 0;
392
393
394
395         FormulaRecordAggregate lastFormulaAggregate = null;
396
397
398
399         for (k = offset; k < records.size(); k++)
400
401         {
402
403             Record rec = ( Record ) records.get(k);
404
405
406
407             if (rec instanceof StringRecord == false && !rec.isInValueSection() && !(rec instanceof UnknownRecord))
408
409             {
410
411                 break;
412
413             }
414
415             if (rec instanceof FormulaRecord)
416
417             {
418
419                 lastFormulaAggregate = new FormulaRecordAggregate((FormulaRecord)rec, null);
420
421                 insertCell( lastFormulaAggregate );
422
423             }
424
425             else if (rec instanceof StringRecord)
426
427             {
428
429                 lastFormulaAggregate.setStringRecord((StringRecord)rec);
430
431             }
432
433             else if (rec instanceof SharedFormulaRecord)
434
435             {
436
437                 //these follow the first formula in a group
438

439                 lastFormulaAggregate.setSharedFormulaRecord((SharedFormulaRecord)rec);
440
441             }
442
443             else if (rec.isValue())
444
445             {
446
447                 insertCell(( CellValueRecordInterface ) rec);
448
449             }
450
451         }
452
453         return k;
454
455     }
456
457
458
459     /**
460
461      * called by the class that is responsible for writing this sucker.
462
463      * Subclasses should implement this so that their data is passed back in a
464
465      * byte array.
466
467      *
468
469      * @param offset to begin writing at
470
471      * @param data byte array containing instance data
472
473      * @return number of bytes written
474
475      */

476
477
478
479     public int serialize(int offset, byte [] data)
480
481     {
482
483       throw new RuntimeException JavaDoc("This method shouldnt be called. ValueRecordsAggregate.serializeCellRow() should be called from RowRecordsAggregate.");
484
485     }
486
487     
488
489     /** Tallies a count of the size of the cell records
490
491      * that are attached to the rows in the range specified.
492
493      */

494
495     public int getRowCellBlockSize(int startRow, int endRow) {
496
497       RowCellIterator itr = new RowCellIterator(startRow, endRow);
498
499       int size = 0;
500
501       while (itr.hasNext()) {
502
503         CellValueRecordInterface cell = (CellValueRecordInterface)itr.next();
504
505         int row = cell.getRow();
506
507         if (row > endRow)
508
509           break;
510
511         if ((row >=startRow) && (row <= endRow))
512
513           size += ((Record)cell).getRecordSize();
514
515       }
516
517       return size;
518
519     }
520
521
522
523     /** Returns true if the row has cells attached to it */
524
525     public boolean rowHasCells(int row) {
526
527       compareRow.setRow(row);
528
529       return records.containsKey(compareRow);
530
531     }
532
533
534
535     /** Serializes the cells that are allocated to a certain row range*/
536
537     public int serializeCellRow(final int row, int offset, byte [] data)
538
539     {
540
541         RowCellIterator itr = new RowCellIterator(row, row);
542
543         int pos = offset;
544
545
546
547         while (itr.hasNext())
548
549         {
550
551             CellValueRecordInterface cell = (CellValueRecordInterface)itr.next();
552
553             if (cell.getRow() != row)
554
555               break;
556
557             pos += (( Record ) cell).serialize(pos, data);
558
559         }
560
561         return pos - offset;
562
563     }
564
565
566
567     
568
569     /**
570
571      * called by the constructor, should set class level fields. Should throw
572
573      * runtime exception for bad/icomplete data.
574
575      *
576
577      * @param data raw data
578
579      * @param size size of data
580
581      * @param offset of the record's data (provided a big array of the file)
582
583      */

584
585
586
587     protected void fillFields(byte [] data, short size, int offset)
588
589     {
590
591     }
592
593
594
595     /**
596
597      * called by constructor, should throw runtime exception in the event of a
598
599      * record passed with a differing ID.
600
601      *
602
603      * @param id alleged id for this record
604
605      */

606
607
608
609     protected void validateSid(short id)
610
611     {
612
613     }
614
615
616
617     /**
618
619      * return the non static version of the id for this record.
620
621      */

622
623
624
625     public short getSid()
626
627     {
628
629         return sid;
630
631     }
632
633
634
635     public int getRecordSize() {
636
637     
638
639         int size = 0;
640
641         Iterator JavaDoc irecs = records.values().iterator();
642
643         
644
645         while (irecs.hasNext()) {
646
647                 size += (( Record ) irecs.next()).getRecordSize();
648
649         }
650
651
652
653         return size;
654
655     }
656
657
658
659     public Iterator JavaDoc getIterator()
660
661     {
662
663         return records.values().iterator();
664
665     }
666
667
668
669     /** Performs a deep clone of the record*/
670
671     public Object JavaDoc clone() {
672
673       ValueRecordsAggregate rec = new ValueRecordsAggregate();
674
675       for (Iterator JavaDoc valIter = getIterator(); valIter.hasNext();) {
676
677         CellValueRecordInterface val = (CellValueRecordInterface)((CellValueRecordInterface)valIter.next()).clone();
678
679         rec.insertCell(val);
680
681       }
682
683       return rec;
684
685     }
686
687 }
Popular Tags