1    
2    
3    /* ====================================================================
4    
5     * The Apache Software License, Version 1.1
6    
7     *
8    
9     * Copyright (c) 2002 The Apache Software Foundation.  All rights
10   
11    * reserved.
12   
13    *
14   
15    * Redistribution and use in source and binary forms, with or without
16   
17    * modification, are permitted provided that the following conditions
18   
19    * are met:
20   
21    *
22   
23    * 1. Redistributions of source code must retain the above copyright
24   
25    *    notice, this list of conditions and the following disclaimer.
26   
27    *
28   
29    * 2. Redistributions in binary form must reproduce the above copyright
30   
31    *    notice, this list of conditions and the following disclaimer in
32   
33    *    the documentation and/or other materials provided with the
34   
35    *    distribution.
36   
37    *
38   
39    * 3. The end-user documentation included with the redistribution,
40   
41    *    if any, must include the following acknowledgment:
42   
43    *       "This product includes software developed by the
44   
45    *        Apache Software Foundation (http://www.apache.org/)."
46   
47    *    Alternately, this acknowledgment may appear in the software itself,
48   
49    *    if and wherever such third-party acknowledgments normally appear.
50   
51    *
52   
53    * 4. The names "Apache" and "Apache Software Foundation" and
54   
55    *    "Apache POI" must not be used to endorse or promote products
56   
57    *    derived from this software without prior written permission. For
58   
59    *    written permission, please contact apache@apache.org.
60   
61    *
62   
63    * 5. Products derived from this software may not be called "Apache",
64   
65    *    "Apache POI", nor may "Apache" appear in their name, without
66   
67    *    prior written permission of the Apache Software Foundation.
68   
69    *
70   
71    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
72   
73    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
74   
75    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76   
77    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
78   
79    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
80   
81    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
82   
83    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
84   
85    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
86   
87    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
88   
89    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
90   
91    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
92   
93    * SUCH DAMAGE.
94   
95    * ====================================================================
96   
97    *
98   
99    * This software consists of voluntary contributions made by many
100  
101   * individuals on behalf of the Apache Software Foundation.  For more
102  
103   * information on the Apache Software Foundation, please see
104  
105   * <http://www.apache.org/>.
106  
107   */
108  
109  
110  
111  package org.apache.poi.hssf.record;
112  
113  
114  
115  import org.apache.poi.util.LittleEndian;
116  
117  
118  
119  import java.util.ArrayList;
120  
121  
122  
123  /**
124  
125   * Title:        Extern Sheet <P>
126  
127   * Description:  A List of Inndexes to SupBook <P>
128  
129   * REFERENCE:  <P>
130  
131   * @author Libin Roman (Vista Portal LDT. Developer)
132  
133   * @version 1.0-pre
134  
135   */
136  
137  
138  
139  public class ExternSheetRecord extends Record {
140  
141      public final static short sid = 0x17;
142  
143      private short             field_1_number_of_REF_sturcutres;
144  
145      private ArrayList         field_2_REF_structures;
146  
147      
148  
149      public ExternSheetRecord() {
150  
151          field_2_REF_structures = new ArrayList();
152  
153      }
154  
155      
156  
157      /**
158  
159       * Constructs a Extern Sheet record and sets its fields appropriately.
160  
161       *
162  
163       * @param id     id must be 0x16 or an exception will be throw upon validation
164  
165       * @param size  the size of the data area of the record
166  
167       * @param data  data of the record (should not contain sid/len)
168  
169       */
170  
171      
172  
173      public ExternSheetRecord(short id, short size, byte[] data) {
174  
175          super(id, size, data);
176  
177      }
178  
179      
180  
181      /**
182  
183       * Constructs a Extern Sheet record and sets its fields appropriately.
184  
185       *
186  
187       * @param id     id must be 0x16 or an exception will be throw upon validation
188  
189       * @param size  the size of the data area of the record
190  
191       * @param data  data of the record (should not contain sid/len)
192  
193       * @param offset of the record's data
194  
195       */
196  
197      public ExternSheetRecord(short id, short size, byte[] data, int offset) {
198  
199          super(id, size, data, offset);
200  
201      }
202  
203      
204  
205      /**
206  
207       * called by constructor, should throw runtime exception in the event of a
208  
209       * record passed with a differing ID.
210  
211       *
212  
213       * @param id alleged id for this record
214  
215       */
216  
217      protected void validateSid(short id) {
218  
219          if (id != sid) {
220  
221              throw new RecordFormatException("NOT An ExternSheet RECORD");
222  
223          }
224  
225      }
226  
227      
228  
229      /**
230  
231       * called by the constructor, should set class level fields.  Should throw
232  
233       * runtime exception for bad/icomplete data.
234  
235       *
236  
237       * @param data raw data
238  
239       * @param size size of data
240  
241       * @param offset of the record's data (provided a big array of the file)
242  
243       */
244  
245      protected void fillFields(byte [] data, short size, int offset) {
246  
247          field_2_REF_structures           = new ArrayList();
248  
249          
250  
251          field_1_number_of_REF_sturcutres = LittleEndian.getShort(data, 0 + offset);
252  
253          
254  
255          int pos = 2 + offset;
256  
257          for (int i = 0 ; i < field_1_number_of_REF_sturcutres ; ++i) {
258  
259              ExternSheetSubRecord rec = new ExternSheetSubRecord((short)0, (short)6 , data , pos);
260  
261              
262  
263              pos += 6;
264  
265              
266  
267              field_2_REF_structures.add( rec);
268  
269          }
270  
271      }
272  
273      
274  
275      /** 
276  
277       * sets the number of the REF structors , that is in Excel file
278  
279       * @param numStruct number of REF structs
280  
281       */
282  
283      public void setNumOfREFStructures(short numStruct) {
284  
285          field_1_number_of_REF_sturcutres = numStruct;
286  
287      }
288  
289      
290  
291      /**  
292  
293       * return the number of the REF structors , that is in Excel file
294  
295       * @return number of REF structs
296  
297       */
298  
299      public short getNumOfREFStructures() {
300  
301          return field_1_number_of_REF_sturcutres;
302  
303      }
304  
305      
306  
307      /** 
308  
309       * adds REF struct (ExternSheetSubRecord)
310  
311       * @param rec REF struct
312  
313       */
314  
315      public void addREFRecord(ExternSheetSubRecord rec) {
316  
317          field_2_REF_structures.add(rec);
318  
319      }
320  
321      
322  
323      /** returns the number of REF Records, which is in model
324  
325       * @return number of REF records
326  
327       */
328  
329      public int getNumOfREFRecords() {
330  
331          return field_2_REF_structures.size();
332  
333      }
334  
335      
336  
337      /** returns the REF record (ExternSheetSubRecord)
338  
339       * @param elem index to place
340  
341       * @return REF record
342  
343       */
344  
345      public ExternSheetSubRecord getREFRecordAt(int elem) {
346  
347          ExternSheetSubRecord result = ( ExternSheetSubRecord ) field_2_REF_structures.get(elem);
348  
349          
350  
351          return result;
352  
353      }
354  
355      
356  
357      public String toString() {
358  
359          StringBuffer buffer = new StringBuffer();
360  
361          
362  
363          buffer.append("[EXTERNSHEET]\n");
364  
365          buffer.append("   numOfRefs     = ").append(getNumOfREFStructures()).append("\n");
366  
367          for (int k=0; k < this.getNumOfREFRecords(); k++) {
368  
369              buffer.append("refrec         #").append(k).append('\n');
370  
371              buffer.append(getREFRecordAt(k).toString());
372  
373              buffer.append("----refrec     #").append(k).append('\n');
374  
375          }
376  
377          buffer.append("[/EXTERNSHEET]\n");
378  
379          
380  
381          
382  
383          return buffer.toString();
384  
385      }
386  
387      
388  
389      /**
390  
391       * called by the class that is responsible for writing this sucker.
392  
393       * Subclasses should implement this so that their data is passed back in a
394  
395       * byte array.
396  
397       *
398  
399       * @param offset to begin writing at
400  
401       * @param data byte array containing instance data
402  
403       * @return number of bytes written
404  
405       */
406  
407      public int serialize(int offset, byte [] data) {
408  
409          LittleEndian.putShort(data, 0 + offset, sid);
410  
411          LittleEndian.putShort(data, 2 + offset,(short)(2 + (getNumOfREFRecords() *6)));
412  
413          
414  
415          LittleEndian.putShort(data, 4 + offset, getNumOfREFStructures());
416  
417          
418  
419          int pos = 6 ;
420  
421          
422  
423          for (int k = 0; k < getNumOfREFRecords(); k++) {
424  
425              ExternSheetSubRecord record = getREFRecordAt(k);
426  
427              System.arraycopy(record.serialize(), 0, data, pos + offset, 6);
428  
429              
430  
431              pos +=6;
432  
433          }
434  
435          return getRecordSize();
436  
437      }
438  
439      
440  
441      public int getRecordSize() {
442  
443          return 4 + 2 + getNumOfREFRecords() * 6;
444  
445      }
446  
447      
448  
449      /**
450  
451       * return the non static version of the id for this record.
452  
453       */
454  
455      public short getSid() {
456  
457          return this.sid;
458  
459      }
460  
461  }
462  
463  ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????ExternSheetRecord????????????????????????????????????????Record???????????????????????????????sid???????????????????????????????field_1_number_of_REF_sturcutres???????????????????????????????field_2_REF_structures????????????ExternSheetRecord?????????field_2_REF_structures???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????ExternSheetRecord???????????????id???????????????????size?????????????????????????data??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????ExternSheetRecord???????????????id???????????????????size?????????????????????????data???????????????????????????????offset?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????validateSid?????????????id???????????????????sid???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????fillFields?????????field_2_REF_structures?????????field_1_number_of_REF_sturcutres????????????????????????????????????????????LittleEndian?????????????????????????????????????????????????????????getShort??????????????????????????????????????????????????????????????????data????????????????????????????????????????????????????????????????????????????offset???????????????????????offset??????????????????????????i??????????????????????????????field_1_number_of_REF_sturcutres???????????????????????????????????????????????????????????????????i?????????????ExternSheetSubRecord??????????????????????????????????????????????????????????????????????????????????????data?????????????????????????????????????????????????????????????????????????????????????????????pos?????????????pos?????????????field_2_REF_structures?????????????????????????????????????????rec???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????setNumOfREFStructures?????????field_1_number_of_REF_sturcutres????????????????????????????????????????????numStruct??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getNumOfREFStructures????????????????field_1_number_of_REF_sturcutres????????????????????????????????????????????????????????????????????????????????????????????????????????????????addREFRecord??????????????????????????????ExternSheetSubRecord?????????field_2_REF_structures????????????????????????????????????rec????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????getNumOfREFRecords????????????????field_2_REF_structures?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????ExternSheetSubRecord?????????????????????????????????getREFRecordAt?????????ExternSheetSubRecord????????????????????????????????????????????????????????????????field_2_REF_structures???????????????????????????????????????????????????????????????????????????????????????????elem????????????????result???????????????????toString?????????buffer?????????buffer?????????????????????????????????????????????????????getNumOfREFStructures???????????????????????k??????????????????????????????????????????????????????k?????????????buffer??????????????????????????????????????????????????????k?????????????buffer???????????????????????????getREFRecordAt??????????????????????????????????????????k?????????????buffer??????????????????????????????????????????????????????k?????????buffer????????????????buffer????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????serialize?????????LittleEndian??????????????????????putShort???????????????????????????????data?????????????????????????????????????????offset?????????????????????????????????????????????????sid?????????LittleEndian??????????????????????putShort???????????????????????????????data?????????????????????????????????????????offset?????????????????????????????????????????????????????????????getNumOfREFRecords?????????LittleEndian??????????????????????putShort???????????????????????????????data?????????????????????????????????????????offset?????????????????????????????????????????????????getNumOfREFStructures?????????????????????????k?????????????????????????????getNumOfREFRecords???????????????????????????????????????????????????k?????????????ExternSheetSubRecord???????????????????????????????????????????getREFRecordAt??????????????????????????????????????????????????????????k??????????????????????????????record?????????????????????????????????????serialize?????????????????????????????????????????????????????data???????????????????????????????????????????????????????????pos?????????????????????????????????????????????????????????????????offset?????????????pos????????????????getRecordSize????????????????getRecordSize????????????????????????getNumOfREFRecords????????????????????????????????????????????????????????????????????????????????????????????????????getSid