1 /
55
56 package org.apache.poi.poifs.eventfilesystem;
57
58 import java.io.*;
59
60 import java.util.*;
61
62 import org.apache.poi.poifs.filesystem.DocumentInputStream;
63 import org.apache.poi.poifs.filesystem.POIFSDocument;
64 import org.apache.poi.poifs.filesystem.POIFSDocumentPath;
65 import org.apache.poi.poifs.property.DirectoryProperty;
66 import org.apache.poi.poifs.property.Property;
67 import org.apache.poi.poifs.property.PropertyTable;
68 import org.apache.poi.poifs.storage.BlockAllocationTableReader;
69 import org.apache.poi.poifs.storage.BlockList;
70 import org.apache.poi.poifs.storage.HeaderBlockReader;
71 import org.apache.poi.poifs.storage.RawDataBlockList;
72 import org.apache.poi.poifs.storage.SmallBlockTableReader;
73
74
84
85 public class POIFSReader
86 {
87 private POIFSReaderRegistry registry;
88 private boolean registryClosed;
89
90
93
94 public POIFSReader()
95 {
96 registry = new POIFSReaderRegistry();
97 registryClosed = false;
98 }
99
100
107
108 public void read(final InputStream stream)
109 throws IOException
110 {
111 registryClosed = true;
112
113
114 HeaderBlockReader header_block_reader = new HeaderBlockReader(stream);
115
116
117 RawDataBlockList data_blocks = new RawDataBlockList(stream);
118
119
120
121 new BlockAllocationTableReader(header_block_reader.getBATCount(),
122 header_block_reader.getBATArray(),
123 header_block_reader.getXBATCount(),
124 header_block_reader.getXBATIndex(),
125 data_blocks);
126
127
128 PropertyTable properties =
129 new PropertyTable(header_block_reader.getPropertyStart(),
130 data_blocks);
131
132
133 processPropertiesgetSmallDocumentBlocks
134 .getSmallDocumentBlocks(data_blocks, properties
135 .getRoot(), header_block_reader
136 .getSBATStart()), data_blocks, properties.getRoot()
137 .getChildren(), new POIFSDocumentPath());
138 }
139
140 /**
141 * Register a POIFSReaderListener for all documents
142 *
143 * @param listener the listener to be registered
144 *
145 * @exception NullPointerException if listener is null
146 * @exception IllegalStateException if read() has already been
147 * called
148 */
149
150 public void registerListener(final POIFSReaderListener listener)
151 {
152 if (listener == null)
153 {
154 throw new NullPointerException();
155 }
156 if (registryClosed)
157 {
158 throw new IllegalStateException();
159 }
160 registry.registerListener(listener);
161 }
162
163 /**
164 * Register a POIFSReaderListener for a document in the root
165 * directory
166 *
167 * @param listener the listener to be registered
168 * @param name the document name
169 *
170 * @exception NullPointerException if listener is null or name is
171 * null or empty
172 * @exception IllegalStateException if read() has already been
173 * called
174 */
175
176 public void registerListener(final POIFSReaderListener listener,
177 final String name)
178 {
179 registerListener(listener, null, name);
180 }
181
182 /**
183 * Register a POIFSReaderListener for a document in the specified
184 * directory
185 *
186 * @param listener the listener to be registered
187 * @param path the document path; if null, the root directory is
188 * assumed
189 * @param name the document name
190 *
191 * @exception NullPointerException if listener is null or name is
192 * null or empty
193 * @exception IllegalStateException if read() has already been
194 * called
195 */
196
197 public void registerListener(final POIFSReaderListener listener,
198 final POIFSDocumentPath path,
199 final String name)
200 {
201 if ((listener == null) || (name == null) || (name.length() == 0))
202 {
203 throw new NullPointerException();
204 }
205 if (registryClosed)
206 {
207 throw new IllegalStateException();
208 }
209 registry.registerListener(listener,
210 (path == null) ? new POIFSDocumentPath()
211 : path, name);
212 }
213
214 /**
215 * read in files
216 *
217 * @param args names of the files
218 *
219 * @exception IOException
220 */
221
222 public static void main(String args[])
223 throws IOException
224 {
225 if (args.length == 0)
226 {
227 System.err
228 .println("at least one argument required: input filename(s)");
229 System.exit(1);
230 }
231
232 // register for all
233 for (int j = 0; j < args.length; j++)
234 {
235 POIFSReader reader = new POIFSReader();
236 POIFSReaderListener listener = new SampleListener();
237
238 reader.registerListener(listener);
239 System.out.println("reading " + args[ j ]);
240 FileInputStream istream = new FileInputStream(args[ j ]);
241
242 reader.read(istream);
243 istream.close();
244 }
245 }
246
247 private void processProperties(final BlockList small_blocks,
248 final BlockList big_blocks,
249 final Iterator properties,
250 final POIFSDocumentPath path)
251 throws IOException
252 {
253 while (properties.hasNext())
254 {
255 Property property = ( Property ) properties.next();
256 String name = property.getName();
257
258 if (property.isDirectory())
259 {
260 POIFSDocumentPath new_path = new POIFSDocumentPath(path,
261 new String[]
262 {
263 name
264 });
265
266 processProperties(
267 small_blocks, big_blocks,
268 (( DirectoryProperty ) property).getChildren(), new_path);
269 }
270 else
271 {
272 int startBlock = property.getStartBlock();
273 Iterator listeners = registry.getListeners(path, name);
274
275 if (listeners.hasNext())
276 {
277 int size = property.getSize();
278 POIFSDocument document = null;
279
280 if (property.shouldUseSmallBlocks())
281 {
282 document =
283 new POIFSDocument(name, small_blocks
284 .fetchBlocks(startBlock), size);
285 }
286 else
287 {
288 document =
289 new POIFSDocument(name, big_blocks
290 .fetchBlocks(startBlock), size);
291 }
292 while (listeners.hasNext())
293 {
294 POIFSReaderListener listener =
295 ( POIFSReaderListener ) listeners.next();
296
297 listener.processPOIFSReaderEvent(
298 new POIFSReaderEvent(
299 new DocumentInputStream(document), path,
300 name));
301 }
302 }
303 else
304 {
305
306 // consume the document's data and discard it
307 if (property.shouldUseSmallBlocks())
308 {
309 small_blocks.fetchBlocks(startBlock);
310 }
311 else
312 {
313 big_blocks.fetchBlocks(startBlock);
314 }
315 }
316 }
317 }
318 }
319
320 private static class SampleListener
321 implements POIFSReaderListener
322 {
323
324 /**
325 * Constructor SampleListener
326 */
327
328 SampleListener()
329 {
330 }
331
332 /**
333 * Method processPOIFSReaderEvent
334 *
335 * @param event
336 */
337
338 public void processPOIFSReaderEvent(final POIFSReaderEvent event)
339 {
340 DocumentInputStream istream = event.getStream();
341 POIFSDocumentPath path = event.getPath();
342 String name = event.getName();
343
344 try
345 {
346 byte[] data = new byte[ istream.available() ];
347
348 istream.read(data);
349 int pathLength = path.length();
350
351 for (int k = 0; k < pathLength; k++)
352 {
353 System.out.print("/" + path.getComponent(k));
354 }
355 System.out.println("/" + name + ": " + data.length
356 + " bytes read");
357 }
358 catch (IOException ignored)
359 {
360 }
361 }
362 } // end private class SampleListener
363 } // end public class POIFSReader
364
365 SmallBlockTableReadergetRootdata_blockspropertiesgetSBATStartheader_block_readergetChildrendata_blockspropertiesgetRootPOIFSDocumentPathregisterListenerPOIFSReaderListenerlistenerregistryClosedregistryregisterListenerlistenerregisterListenerPOIFSReaderListenerregisterListenerlistenernameregisterListenerPOIFSReaderListenerPOIFSDocumentPathlistenernamenameregistryClosedregistryregisterListenerlistenerpathPOIFSDocumentPathpathnamemainargsjargsjPOIFSReaderPOIFSReaderPOIFSReaderListenerSampleListenerreaderregisterListenerlistenerargsjargsjreaderreadistreamistreamprocessPropertiesBlockListBlockListPOIFSDocumentPathpropertiesPropertyPropertypropertiespropertygetNamepropertyisDirectoryPOIFSDocumentPathPOIFSDocumentPathpathnameprocessPropertiessmall_blocksbig_blocksDirectoryPropertypropertynew_pathpropertygetStartBlockregistrygetListenerspathnamelistenerspropertygetSizePOIFSDocumentpropertyshouldUseSmallBlocksdocumentPOIFSDocumentfetchBlocksnamesmall_blocksstartBlocksizedocumentPOIFSDocumentfetchBlocksnamebig_blocksstartBlocksizelistenersPOIFSReaderListenerPOIFSReaderListenerlistenerslistenerprocessPOIFSReaderEventPOIFSReaderEventDocumentInputStreamdocumentpathnamepropertyshouldUseSmallBlockssmall_blocksfetchBlocksstartBlockbig_blocksfetchBlocksstartBlockSampleListenerPOIFSReaderListenerSampleListenerprocessPOIFSReaderEventPOIFSReaderEventDocumentInputStreameventgetStreamPOIFSDocumentPatheventgetPatheventgetNamebyteistreamavailableistreamreaddatapathlengthkpathLengthkpathgetComponentknamedata