KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hwpf > model > ListTables


1 /* ====================================================================
2    Copyright 2003-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 package org.apache.poi.hwpf.model;
19
20 import org.apache.poi.util.LittleEndian;
21
22 import org.apache.poi.hwpf.model.io.*;
23
24 import java.util.HashMap JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.NoSuchElementException JavaDoc;
28
29 import java.io.ByteArrayOutputStream JavaDoc;
30 import java.io.IOException JavaDoc;
31
32 /**
33  * @author Ryan Ackley
34  */

35 public class ListTables
36 {
37   private static final int LIST_DATA_SIZE = 28;
38   private static final int LIST_FORMAT_OVERRIDE_SIZE = 16;
39
40   HashMap JavaDoc _listMap = new HashMap JavaDoc();
41   ArrayList JavaDoc _overrideList = new ArrayList JavaDoc();
42
43   public ListTables()
44   {
45
46   }
47
48   public ListTables(byte[] tableStream, int lstOffset, int lfoOffset)
49   {
50     // get the list data
51
int length = LittleEndian.getShort(tableStream, lstOffset);
52     lstOffset += LittleEndian.SHORT_SIZE;
53     int levelOffset = lstOffset + (length * LIST_DATA_SIZE);
54
55     for (int x = 0; x < length; x++)
56     {
57       ListData lst = new ListData(tableStream, lstOffset);
58       _listMap.put(new Integer JavaDoc(lst.getLsid()), lst);
59       lstOffset += LIST_DATA_SIZE;
60
61       int num = lst.numLevels();
62       for (int y = 0; y < num; y++)
63       {
64         ListLevel lvl = new ListLevel(tableStream, levelOffset);
65         lst.setLevel(y, lvl);
66         levelOffset += lvl.getSizeInBytes();
67       }
68     }
69
70     // now get the list format overrides. The size is an int unlike the LST size
71
length = LittleEndian.getInt(tableStream, lfoOffset);
72     lfoOffset += LittleEndian.INT_SIZE;
73     int lfolvlOffset = lfoOffset + (LIST_FORMAT_OVERRIDE_SIZE * length);
74     for (int x = 0; x < length; x++)
75     {
76       ListFormatOverride lfo = new ListFormatOverride(tableStream, lfoOffset);
77       lfoOffset += LIST_FORMAT_OVERRIDE_SIZE;
78       int num = lfo.numOverrides();
79       for (int y = 0; y < num; y++)
80       {
81         while(tableStream[lfolvlOffset] == -1)
82         {
83           lfolvlOffset++;
84         }
85         ListFormatOverrideLevel lfolvl = new ListFormatOverrideLevel(tableStream, lfolvlOffset);
86         lfo.setOverride(y, lfolvl);
87         lfolvlOffset += lfolvl.getSizeInBytes();
88       }
89       _overrideList.add(lfo);
90     }
91   }
92
93   public int addList(ListData lst, ListFormatOverride override)
94   {
95     int lsid = lst.getLsid();
96     while (_listMap.get(new Integer JavaDoc(lsid)) != null)
97     {
98       lsid = lst.resetListID();
99       override.setLsid(lsid);
100     }
101     _listMap.put(new Integer JavaDoc(lsid), lst);
102     _overrideList.add(override);
103     return lsid;
104   }
105
106   public void writeListDataTo(HWPFOutputStream tableStream)
107     throws IOException JavaDoc
108   {
109
110     Integer JavaDoc[] intList = (Integer JavaDoc[])_listMap.keySet().toArray(new Integer JavaDoc[0]);
111
112     // use this stream as a buffer for the levels since their size varies.
113
ByteArrayOutputStream JavaDoc levelBuf = new ByteArrayOutputStream JavaDoc();
114
115     // use a byte array for the lists because we know their size.
116
byte[] listBuf = new byte[intList.length * LIST_DATA_SIZE];
117
118     byte[] shortHolder = new byte[2];
119     LittleEndian.putShort(shortHolder, (short)intList.length);
120     tableStream.write(shortHolder);
121
122     for (int x = 0; x < intList.length; x++)
123     {
124       ListData lst = (ListData)_listMap.get(intList[x]);
125       tableStream.write(lst.toByteArray());
126       ListLevel[] lvls = lst.getLevels();
127       for (int y = 0; y < lvls.length; y++)
128       {
129         levelBuf.write(lvls[y].toByteArray());
130       }
131     }
132     tableStream.write(levelBuf.toByteArray());
133   }
134
135   public void writeListOverridesTo(HWPFOutputStream tableStream)
136     throws IOException JavaDoc
137   {
138
139     // use this stream as a buffer for the levels since their size varies.
140
ByteArrayOutputStream JavaDoc levelBuf = new ByteArrayOutputStream JavaDoc();
141
142     int size = _overrideList.size();
143
144     byte[] intHolder = new byte[4];
145     LittleEndian.putInt(intHolder, size);
146     tableStream.write(intHolder);
147
148     for (int x = 0; x < size; x++)
149     {
150       ListFormatOverride lfo = (ListFormatOverride)_overrideList.get(x);
151       tableStream.write(lfo.toByteArray());
152       ListFormatOverrideLevel[] lfolvls = lfo.getLevelOverrides();
153       for (int y = 0; y < lfolvls.length; y++)
154       {
155         levelBuf.write(lfolvls[y].toByteArray());
156       }
157     }
158     tableStream.write(levelBuf.toByteArray());
159
160   }
161
162   public ListFormatOverride getOverride(int lfoIndex)
163   {
164     return (ListFormatOverride)_overrideList.get(lfoIndex - 1);
165   }
166
167   public int getOverrideIndexFromListID(int lstid)
168   {
169     int returnVal = -1;
170     int size = _overrideList.size();
171     for (int x = 0; x < size; x++)
172     {
173       ListFormatOverride next = (ListFormatOverride)_overrideList.get(x);
174       if (next.getLsid() == lstid)
175       {
176         // 1-based index I think
177
returnVal = x+1;
178         break;
179       }
180     }
181     if (returnVal == -1)
182     {
183       throw new NoSuchElementException JavaDoc("No list found with the specified ID");
184     }
185     return returnVal;
186   }
187
188   public ListLevel getLevel(int listID, int level)
189   {
190     ListData lst = (ListData)_listMap.get(new Integer JavaDoc(listID));
191     ListLevel lvl = lst.getLevels()[level];
192     return lvl;
193   }
194
195   public ListData getListData(int listID)
196   {
197     return (ListData) _listMap.get(new Integer JavaDoc(listID));
198   }
199
200   public boolean equals(Object JavaDoc obj)
201   {
202     if (obj == null)
203     {
204       return false;
205     }
206
207     ListTables tables = (ListTables)obj;
208
209     if (_listMap.size() == tables._listMap.size())
210     {
211       Iterator JavaDoc it = _listMap.keySet().iterator();
212       while (it.hasNext())
213       {
214         Object JavaDoc key = it.next();
215         ListData lst1 = (ListData)_listMap.get(key);
216         ListData lst2 = (ListData)tables._listMap.get(key);
217         if (!lst1.equals(lst2))
218         {
219           return false;
220         }
221       }
222       int size = _overrideList.size();
223       if (size == tables._overrideList.size())
224       {
225         for (int x = 0; x < size; x++)
226         {
227           if (!_overrideList.get(x).equals(tables._overrideList.get(x)))
228           {
229             return false;
230           }
231         }
232         return true;
233       }
234     }
235     return false;
236   }
237 }
238
Popular Tags