KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jxl > write > biff > SupbookRecord


1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/

19
20 package jxl.write.biff;
21
22 import common.Assert;
23 import common.Logger;
24
25 import jxl.biff.Type;
26 import jxl.biff.IntegerHelper;
27 import jxl.biff.StringHelper;
28 import jxl.biff.EncodedURLHelper;
29 import jxl.biff.WritableRecordData;
30 import jxl.WorkbookSettings;
31
32 /**
33  * Stores the supporting workbook information. For files written by
34  * JExcelApi this will only reference internal sheets
35  */

36 class SupbookRecord extends WritableRecordData
37 {
38   /**
39    * The logger
40    */

41   private static Logger logger = Logger.getLogger(SupbookRecord.class);
42
43   /**
44    * The type of this supbook record
45    */

46   private SupbookType type;
47
48   /**
49    * The data to be written to the binary file
50    */

51   private byte[] data;
52
53   /**
54    * The number of sheets - internal & external supbooks only
55    */

56   private int numSheets;
57
58   /**
59    * The name of the external file
60    */

61   private String JavaDoc fileName;
62
63   /**
64    * The names of the external sheets
65    */

66   private String JavaDoc[] sheetNames;
67
68   /**
69    * The workbook settings
70    */

71   private WorkbookSettings workbookSettings;
72
73   /**
74    * The type of supbook this refers to
75    */

76   private static class SupbookType {};
77
78   public final static SupbookType INTERNAL = new SupbookType();
79   public final static SupbookType EXTERNAL = new SupbookType();
80   public final static SupbookType ADDIN = new SupbookType();
81   public final static SupbookType LINK = new SupbookType();
82   public final static SupbookType UNKNOWN = new SupbookType();
83
84   /**
85    * Constructor for internal sheets
86    */

87   public SupbookRecord(int sheets, WorkbookSettings ws)
88   {
89     super(Type.SUPBOOK);
90
91     numSheets = sheets;
92     type = INTERNAL;
93     workbookSettings = ws;
94   }
95
96   /**
97    * Constructor for external sheets
98    *
99    * @param fn the filename of the external supbook
100    * @param ws the workbook settings
101    */

102   public SupbookRecord(String JavaDoc fn, WorkbookSettings ws)
103   {
104     super(Type.SUPBOOK);
105
106     fileName = fn;
107     numSheets = 1;
108     sheetNames = new String JavaDoc[0];
109     workbookSettings = ws;
110
111     type = EXTERNAL;
112   }
113
114   /**
115    * Constructor used when copying from an external workbook
116    */

117   public SupbookRecord(jxl.read.biff.SupbookRecord sr, WorkbookSettings ws)
118   {
119     super(Type.SUPBOOK);
120
121     workbookSettings = ws;
122     if (sr.getType() == sr.INTERNAL)
123     {
124       type = INTERNAL;
125       numSheets = sr.getNumberOfSheets();
126     }
127     else if (sr.getType() == sr.EXTERNAL)
128     {
129       type = EXTERNAL;
130       numSheets = sr.getNumberOfSheets();
131       fileName = sr.getFileName();
132       sheetNames = new String JavaDoc[numSheets];
133
134       for (int i = 0; i < numSheets; i++)
135       {
136         sheetNames[i] = sr.getSheetName(i);
137       }
138     }
139   }
140
141   /**
142    * Initializes an internal supbook record
143    *
144    * @param sr the read supbook record to copy from
145    */

146   private void initInternal(jxl.read.biff.SupbookRecord sr)
147   {
148     numSheets = sr.getNumberOfSheets();
149     initInternal();
150   }
151
152   /**
153    * Initializes an internal supbook record
154    */

155   private void initInternal()
156   {
157     data = new byte[4];
158
159     IntegerHelper.getTwoBytes(numSheets, data, 0);
160     data[2] = 0x1;
161     data[3] = 0x4;
162     type = INTERNAL;
163   }
164
165   /**
166    * Adjust the number of internal sheets. Called by WritableSheet when
167    * a sheet is added or or removed to the workbook
168    *
169    * @param sheets the new number of sheets
170    */

171   void adjustInternal(int sheets)
172   {
173     Assert.verify(type == INTERNAL);
174     numSheets = sheets;
175     initInternal();
176   }
177
178   /**
179    * Initializes an external supbook record
180    */

181   private void initExternal()
182   {
183     int totalSheetNameLength = 0;
184     for (int i = 0; i < numSheets; i++)
185     {
186       totalSheetNameLength += sheetNames[i].length();
187     }
188
189     byte[] fileNameData = EncodedURLHelper.getEncodedURL(fileName,
190                                                          workbookSettings);
191     int dataLength = 2 + // numsheets
192
4 + fileNameData.length +
193       numSheets * 3 + totalSheetNameLength * 2;
194       
195     data = new byte[dataLength];
196
197     IntegerHelper.getTwoBytes(numSheets, data, 0);
198     
199     // Add in the file name. Precede with a byte denoting that it is a
200
// file name
201
int pos = 2;
202     IntegerHelper.getTwoBytes(fileNameData.length+1, data, pos);
203     data[pos+2] = 0; // ascii indicator
204
data[pos+3] = 1; // file name indicator
205
System.arraycopy(fileNameData, 0, data, pos+4, fileNameData.length);
206
207     pos += 4 + fileNameData.length;
208
209     // Get the sheet names
210
for (int i = 0; i < sheetNames.length; i++)
211     {
212       IntegerHelper.getTwoBytes(sheetNames[i].length(), data, pos);
213       data[pos+2] = 1; // unicode indicator
214
StringHelper.getUnicodeBytes(sheetNames[i], data, pos+3);
215       pos += 3 + sheetNames[i].length() * 2;
216     }
217   }
218
219   /**
220    * The binary data to be written out
221    *
222    * @return the binary data
223    */

224   public byte[] getData()
225   {
226     if (type == INTERNAL)
227     {
228       initInternal();
229     }
230     else if (type == EXTERNAL)
231     {
232       initExternal();
233     }
234     else
235     {
236       logger.warn("unsupported supbook type - defaulting to internal");
237       initInternal();
238     }
239
240     return data;
241   }
242
243   /**
244    * Gets the type of this supbook record
245    *
246    * @return the type of this supbook
247    */

248   public SupbookType getType()
249   {
250     return type;
251   }
252
253   /**
254    * Gets the number of sheets. This will only be non-zero for internal
255    * and external supbooks
256    *
257    * @return the number of sheets
258    */

259   public int getNumberOfSheets()
260   {
261     return numSheets;
262   }
263
264   /**
265    * Accessor for the file name
266    *
267    * @return the file name
268    */

269   public String JavaDoc getFileName()
270   {
271     return fileName;
272   }
273
274   /**
275    * Adds the worksheet name to this supbook
276    *
277    * @param name the worksheet name
278    * @return the index of this sheet in the supbook record
279    */

280   public int getSheetIndex(String JavaDoc s)
281   {
282     boolean found = false;
283     int sheetIndex = 0;
284     for (int i = 0; i < sheetNames.length && !found; i++)
285     {
286       if (sheetNames[i].equals(s))
287       {
288         found = true;
289         sheetIndex = 0;
290       }
291     }
292
293     if (found)
294     {
295       return sheetIndex;
296     }
297
298     // Grow the array
299
String JavaDoc[] names = new String JavaDoc[sheetNames.length + 1];
300     names[sheetNames.length] = s;
301     sheetNames = names;
302     return sheetNames.length - 1;
303   }
304
305   /**
306    * Accessor for the sheet name
307    *
308    * @param s the sheet index
309    */

310   public String JavaDoc getSheetName(int s)
311   {
312     return sheetNames[s];
313   }
314 }
315
Popular Tags