1 2 17 18 19 package org.apache.poi.poifs.filesystem; 20 21 import java.io.*; 22 23 import java.util.*; 24 25 import org.apache.poi.poifs.common.POIFSConstants; 26 import org.apache.poi.poifs.dev.POIFSViewable; 27 import org.apache.poi.poifs.property.DirectoryProperty; 28 import org.apache.poi.poifs.property.DocumentProperty; 29 import org.apache.poi.poifs.property.Property; 30 import org.apache.poi.poifs.property.PropertyTable; 31 import org.apache.poi.poifs.storage.BATBlock; 32 import org.apache.poi.poifs.storage.BlockAllocationTableReader; 33 import org.apache.poi.poifs.storage.BlockAllocationTableWriter; 34 import org.apache.poi.poifs.storage.BlockList; 35 import org.apache.poi.poifs.storage.BlockWritable; 36 import org.apache.poi.poifs.storage.HeaderBlockReader; 37 import org.apache.poi.poifs.storage.HeaderBlockWriter; 38 import org.apache.poi.poifs.storage.RawDataBlock; 39 import org.apache.poi.poifs.storage.RawDataBlockList; 40 import org.apache.poi.poifs.storage.SmallBlockTableReader; 41 import org.apache.poi.poifs.storage.SmallBlockTableWriter; 42 import org.apache.poi.poifs.storage.SmallDocumentBlock; 43 44 50 51 public class POIFSFileSystem 52 implements POIFSViewable 53 { 54 private PropertyTable _property_table; 55 private List _documents; 56 private DirectoryNode _root; 57 58 61 62 public POIFSFileSystem() 63 { 64 _property_table = new PropertyTable(); 65 _documents = new ArrayList(); 66 _root = null; 67 } 68 69 76 77 public POIFSFileSystem(final InputStream stream) 78 throws IOException 79 { 80 this(); 81 82 HeaderBlockReader header_block_reader = new HeaderBlockReader(stream); 84 85 RawDataBlockList data_blocks = new RawDataBlockList(stream); 87 88 new BlockAllocationTableReader(header_block_reader.getBATCount(), 91 header_block_reader.getBATArray(), 92 header_block_reader.getXBATCount(), 93 header_block_reader.getXBATIndex(), 94 data_blocks); 95 96 PropertyTable properties = 98 new PropertyTable(header_block_reader.getPropertyStart(), 99 data_blocks); 100 101 processProperties(SmallBlockTableReader 103 .getSmallDocumentBlocks(data_blocks, properties 104 .getRoot(), header_block_reader 105 .getSBATStart()), data_blocks, properties.getRoot() 106 .getChildren(), null); 107 } 108 109 120 121 public DocumentEntry createDocument(final InputStream stream, 122 final String name) 123 throws IOException 124 { 125 return getRoot().createDocument(name, stream); 126 } 127 128 140 141 public DocumentEntry createDocument(final String name, final int size, 142 final POIFSWriterListener writer) 143 throws IOException 144 { 145 return getRoot().createDocument(name, size, writer); 146 } 147 148 157 158 public DirectoryEntry createDirectory(final String name) 159 throws IOException 160 { 161 return getRoot().createDirectory(name); 162 } 163 164 172 173 public void writeFilesystem(final OutputStream stream) 174 throws IOException 175 { 176 177 _property_table.preWrite(); 179 180 SmallBlockTableWriter sbtw = 182 new SmallBlockTableWriter(_documents, _property_table.getRoot()); 183 184 BlockAllocationTableWriter bat = 186 new BlockAllocationTableWriter(); 187 188 List bm_objects = new ArrayList(); 191 192 bm_objects.addAll(_documents); 193 bm_objects.add(_property_table); 194 bm_objects.add(sbtw); 195 bm_objects.add(sbtw.getSBAT()); 196 197 Iterator iter = bm_objects.iterator(); 200 201 while (iter.hasNext()) 202 { 203 BATManaged bmo = ( BATManaged ) iter.next(); 204 int block_count = bmo.countBlocks(); 205 206 if (block_count != 0) 207 { 208 bmo.setStartBlock(bat.allocateSpace(block_count)); 209 } 210 else 211 { 212 213 } 217 } 218 219 int batStartBlock = bat.createBlocks(); 222 223 HeaderBlockWriter header_block_writer = new HeaderBlockWriter(); 225 BATBlock[] xbat_blocks = 226 header_block_writer.setBATBlocks(bat.countBlocks(), 227 batStartBlock); 228 229 header_block_writer.setPropertyStart(_property_table.getStartBlock()); 231 232 header_block_writer.setSBATStart(sbtw.getSBAT().getStartBlock()); 234 235 header_block_writer.setSBATBlockCount(sbtw.getSBATBlockCount()); 237 238 List writers = new ArrayList(); 244 245 writers.add(header_block_writer); 246 writers.addAll(_documents); 247 writers.add(_property_table); 248 writers.add(sbtw); 249 writers.add(sbtw.getSBAT()); 250 writers.add(bat); 251 for (int j = 0; j < xbat_blocks.length; j++) 252 { 253 writers.add(xbat_blocks[ j ]); 254 } 255 256 iter = writers.iterator(); 258 while (iter.hasNext()) 259 { 260 BlockWritable writer = ( BlockWritable ) iter.next(); 261 262 writer.writeBlocks(stream); 263 } 264 } 265 266 274 275 public static void main(String args[]) 276 throws IOException 277 { 278 if (args.length != 2) 279 { 280 System.err.println( 281 "two arguments required: input filename and output filename"); 282 System.exit(1); 283 } 284 FileInputStream istream = new FileInputStream(args[ 0 ]); 285 FileOutputStream ostream = new FileOutputStream(args[ 1 ]); 286 287 new POIFSFileSystem(istream).writeFilesystem(ostream); 288 istream.close(); 289 ostream.close(); 290 } 291 292 297 298 public DirectoryEntry getRoot() 299 { 300 if (_root == null) 301 { 302 _root = new DirectoryNode(_property_table.getRoot(), this, null); 303 } 304 return _root; 305 } 306 307 317 318 public DocumentInputStream createDocumentInputStream( 319 final String documentName) 320 throws IOException 321 { 322 Entry document = getRoot().getEntry(documentName); 323 324 if (!document.isDocumentEntry()) 325 { 326 throw new IOException("Entry '" + documentName 327 + "' is not a DocumentEntry"); 328 } 329 return new DocumentInputStream(( DocumentEntry ) document); 330 } 331 332 337 338 void addDocument(final POIFSDocument document) 339 { 340 _documents.add(document); 341 _property_table.addProperty(document.getDocumentProperty()); 342 } 343 344 349 350 void addDirectory(final DirectoryProperty directory) 351 { 352 _property_table.addProperty(directory); 353 } 354 355 360 361 void remove(EntryNode entry) 362 { 363 _property_table.removeProperty(entry.getProperty()); 364 if (entry.isDocumentEntry()) 365 { 366 _documents.remove((( DocumentNode ) entry).getDocument()); 367 } 368 } 369 370 private void processProperties(final BlockList small_blocks, 371 final BlockList big_blocks, 372 final Iterator properties, 373 final DirectoryNode dir) 374 throws IOException 375 { 376 while (properties.hasNext()) 377 { 378 Property property = ( Property ) properties.next(); 379 String name = property.getName(); 380 DirectoryNode parent = (dir == null) 381 ? (( DirectoryNode ) getRoot()) 382 : dir; 383 384 if (property.isDirectory()) 385 { 386 DirectoryNode new_dir = 387 ( DirectoryNode ) parent.createDirectory(name); 388 389 new_dir.setStorageClsid( property.getStorageClsid() ); 390 391 processProperties( 392 small_blocks, big_blocks, 393 (( DirectoryProperty ) property).getChildren(), new_dir); 394 } 395 else 396 { 397 int startBlock = property.getStartBlock(); 398 int size = property.getSize(); 399 POIFSDocument document = null; 400 401 if (property.shouldUseSmallBlocks()) 402 { 403 document = 404 new POIFSDocument(name, small_blocks 405 .fetchBlocks(startBlock), size); 406 } 407 else 408 { 409 document = 410 new POIFSDocument(name, 411 big_blocks.fetchBlocks(startBlock), 412 size); 413 } 414 parent.createDocument(document); 415 } 416 } 417 } 418 419 420 421 427 428 public Object [] getViewableArray() 429 { 430 if (preferArray()) 431 { 432 return (( POIFSViewable ) getRoot()).getViewableArray(); 433 } 434 else 435 { 436 return new Object [ 0 ]; 437 } 438 } 439 440 447 448 public Iterator getViewableIterator() 449 { 450 if (!preferArray()) 451 { 452 return (( POIFSViewable ) getRoot()).getViewableIterator(); 453 } 454 else 455 { 456 return Collections.EMPTY_LIST.iterator(); 457 } 458 } 459 460 467 468 public boolean preferArray() 469 { 470 return (( POIFSViewable ) getRoot()).preferArray(); 471 } 472 473 479 480 public String getShortDescription() 481 { 482 return "POIFS FileSystem"; 483 } 484 485 486 } 488 | Popular Tags |