1 /
55
56 package org.apache.poi.poifs.property;
57
58 import java.io.IOException;
59 import java.io.OutputStream;
60
61 import java.util.*;
62
63 import org.apache.poi.poifs.common.POIFSConstants;
64 import org.apache.poi.poifs.filesystem.BATManaged;
65 import org.apache.poi.poifs.storage.BlockWritable;
66 import org.apache.poi.poifs.storage.PropertyBlock;
67 import org.apache.poi.poifs.storage.RawDataBlock;
68 import org.apache.poi.poifs.storage.RawDataBlockList;
69
70
77
78 public class PropertyTable
79 implements BATManaged, BlockWritable
80 {
81 private int _start_block;
82 private List _properties;
83 private BlockWritable[] _blocks;
84
85
88
89 public PropertyTable()
90 {
91 _start_block = POIFSConstants.END_OF_CHAIN;
92 _properties = new ArrayList();
93 addProperty(new RootProperty());
94 _blocks = null;
95 }
96
97
108
109 public PropertyTable(final int startBlock,
110 final RawDataBlockList blockList)
111 throws IOException
112 {
113 _start_block = POIFSConstants.END_OF_CHAIN;
114 _blocks = null;
115 _properties =
116 PropertyFactory
117 .convertToProperties(blockList.fetchBlocks(startBlock));
118 populatePropertyTree(( DirectoryProperty ) _properties.get(0));
119 }
120
121 /**
122 * Add a property to the list of properties we manage
123 *
124 * @param property the new Property to manage
125 */
126
127 public void addProperty(final Property property)
128 {
129 _properties.add(property);
130 }
131
132 /**
133 * Remove a property from the list of properties we manage
134 *
135 * @param property the Property to be removed
136 */
137
138 public void removeProperty(final Property property)
139 {
140 _properties.remove(property);
141 }
142
143 /**
144 * Get the root property
145 *
146 * @return the root property
147 */
148
149 public RootProperty getRoot()
150 {
151
152 // it's always the first element in the List
153 return ( RootProperty ) _properties.get(0);
154 }
155
156 /**
157 * Prepare to be written
158 */
159
160 public void preWrite()
161 {
162 Property[] properties =
163 ( Property [] ) _properties.toArray(new Property[ 0 ]);
164
165 // give each property its index
166 for (int k = 0; k < properties.length; k++)
167 {
168 properties[ k ].setIndex(k);
169 }
170
171 // allocate the blocks for the property table
172 _blocks = PropertyBlock.createPropertyBlockArray(_properties);
173
174 // prepare each property for writing
175 for (int k = 0; k < properties.length; k++)
176 {
177 properties[ k ].preWrite();
178 }
179 }
180
181 /**
182 * Get the start block for the property table
183 *
184 * @return start block index
185 */
186
187 public int getStartBlock()
188 {
189 return _start_block;
190 }
191
192 private void populatePropertyTree(DirectoryProperty root)
193 throws IOException
194 {
195 int index = root.getChildIndex();
196
197 if (!Property.isValidIndex(index))
198 {
199
200 // property has no children
201 return;
202 }
203 Stack children = new Stack();
204
205 children.push(_properties.get(index));
206 while (!children.empty())
207 {
208 Property property = ( Property ) children.pop();
209
210 root.addChild(property);
211 if (property.isDirectory())
212 {
213 populatePropertyTree(( DirectoryProperty ) property);
214 }
215 index = property.getPreviousChildIndex();
216 if (Property.isValidIndex(index))
217 {
218 children.push(_properties.get(index));
219 }
220 index = property.getNextChildIndex();
221 if (Property.isValidIndex(index))
222 {
223 children.push(_properties.get(index));
224 }
225 }
226 }
227
228 /* ********** START implementation of BATManaged ********** */
229
230 /**
231 * Return the number of BigBlock's this instance uses
232 *
233 * @return count of BigBlock instances
234 */
235
236 public int countBlocks()
237 {
238 return (_blocks == null) ? 0
239 : _blocks.length;
240 }
241
242 /**
243 * Set the start block for this instance
244 *
245 * @param index index into the array of BigBlock instances making
246 * up the the filesystem
247 */
248
249 public void setStartBlock(final int index)
250 {
251 _start_block = index;
252 }
253
254 /* ********** END implementation of BATManaged ********** */
255 /* ********** START implementation of BlockWritable ********** */
256
257 /**
258 * Write the storage to an OutputStream
259 *
260 * @param stream the OutputStream to which the stored data should
261 * be written
262 *
263 * @exception IOException on problems writing to the specified
264 * stream
265 */
266
267 public void writeBlocks(final OutputStream stream)
268 throws IOException
269 {
270 if (_blocks != null)
271 {
272 for (int j = 0; j < _blocks.length; j++)
273 {
274 _blocks[ j ].writeBlocks(stream);
275 }
276 }
277 }
278
279 /* ********** END implementation of BlockWritable ********** */
280 } // end public class PropertyTable
281
282 ??????????????????convertToProperties??????????????????????????????????????blockList????????????????????????????????????????????????fetchBlocks????????????????????????????????????????????????????????????startBlock?????????populatePropertyTree????????????????????????????????DirectoryProperty????????????????????????????????????????????????????_properties??????????????????????addProperty???????????????????????????????????Property?????????_properties?????????????????????????property??????????????????????removeProperty??????????????????????????????????????Property?????????_properties????????????????????????????property?????????????????RootProperty?????????????????????????getRoot???????????????????????????RootProperty?????????????????????????????????_properties??????????????????????preWrite?????????Property???????????????Property?????????????????????????????_properties?????????????????????????????????????????????????????Property??????????????????????????????????k?????????????????????????????properties????????????????????????????????????????????????k?????????????properties?????????????????????????k?????????????????????????????setIndex??????????????????????????????????????k??????????????????_blocks???????????????????PropertyBlock?????????????????????????????????createPropertyBlockArray??????????????????????????????????????????????????????????_properties??????????????????????????????????k?????????????????????????????properties????????????????????????????????????????????????k?????????????properties?????????????????????????k?????????????????????????????preWrite?????????????????????getStartBlock????????????????_start_block??????????????????populatePropertyTree???????????????????????????????????????DirectoryProperty?????????????????????root??????????????????????????getChildIndex??????????????Property???????????????????????isValidIndex????????????????????????????????????index??????????????????????children???????????????????????_properties???????????????????????????????????????index?????????????????children?????????????Property???????????????????????????????????Property??????????????????????????????????????????????children?????????????root??????????????????addChild???????????????????????????property?????????????????property??????????????????????????isDirectory?????????????????populatePropertyTree????????????????????????????????????????DirectoryProperty????????????????????????????????????????????????????????????property?????????????index?????????????????????property??????????????????????????????getPreviousChildIndex?????????????????Property??????????????????????????isValidIndex???????????????????????????????????????index?????????????????children???????????????????????????????_properties???????????????????????????????????????????????index?????????????index?????????????????????property??????????????????????????????getNextChildIndex?????????????????Property??????????????????????????isValidIndex???????????????????????????????????????index?????????????????children???????????????????????????????_properties???????????????????????????????????????????????index??????????????????????????countBlocks?????????????????_blocks????????????????????????????????????_blocks??????????????????????setStartBlock?????????_start_block????????????????????????index????????????????????????????????writeBlocks?????????????_blocks?????????????????????????????j?????????????????????????????????_blocks?????????????????????????????????????????????????j?????????????????_blocks??????????????????????????j??????????????????????????????writeBlocks??????????????????????????????????????????stream??????????