FileDocCategorySizeDatePackage
POIFSFileSystem.javaAPI DocApache Poi 3.0.115375Mon Jan 01 12:39:34 GMT 2007org.apache.poi.poifs.filesystem

POIFSFileSystem

public class POIFSFileSystem extends Object implements POIFSViewable
This is the main class of the POIFS system; it manages the entire life cycle of the filesystem.
author
Marc Johnson (mjohnson at apache dot org)

Fields Summary
private PropertyTable
_property_table
private List
_documents
private DirectoryNode
_root
Constructors Summary
public POIFSFileSystem()
Constructor, intended for writing

        _property_table = new PropertyTable();
        _documents      = new ArrayList();
        _root           = null;
    
public POIFSFileSystem(InputStream stream)
Create a POIFSFileSystem from an InputStream

param
stream the InputStream from which to read the data
exception
IOException on errors reading, or on invalid data

        this();

        // read the header block from the stream
        HeaderBlockReader header_block_reader = new HeaderBlockReader(stream);

        // read the rest of the stream into blocks
        RawDataBlockList  data_blocks         = new RawDataBlockList(stream);

        // set up the block allocation table (necessary for the
        // data_blocks to be manageable
        new BlockAllocationTableReader(header_block_reader.getBATCount(),
                                       header_block_reader.getBATArray(),
                                       header_block_reader.getXBATCount(),
                                       header_block_reader.getXBATIndex(),
                                       data_blocks);

        // get property table from the document
        PropertyTable properties =
            new PropertyTable(header_block_reader.getPropertyStart(),
                              data_blocks);

        // init documents
        processProperties(SmallBlockTableReader
            .getSmallDocumentBlocks(data_blocks, properties
                .getRoot(), header_block_reader
                    .getSBATStart()), data_blocks, properties.getRoot()
                        .getChildren(), null);
    
Methods Summary
voidaddDirectory(org.apache.poi.poifs.property.DirectoryProperty directory)
add a new DirectoryProperty

param
directory the DirectoryProperty being added

        _property_table.addProperty(directory);
    
voidaddDocument(org.apache.poi.poifs.filesystem.POIFSDocument document)
add a new POIFSDocument

param
document the POIFSDocument being added

        _documents.add(document);
        _property_table.addProperty(document.getDocumentProperty());
    
public org.apache.poi.poifs.filesystem.DirectoryEntrycreateDirectory(java.lang.String name)
create a new DirectoryEntry in the root directory

param
name the name of the new DirectoryEntry
return
the new DirectoryEntry
exception
IOException on name duplication

        return getRoot().createDirectory(name);
    
public org.apache.poi.poifs.filesystem.DocumentEntrycreateDocument(java.io.InputStream stream, java.lang.String name)
Create a new document to be added to the root directory

param
stream the InputStream from which the document's data will be obtained
param
name the name of the new POIFSDocument
return
the new DocumentEntry
exception
IOException on error creating the new POIFSDocument

        return getRoot().createDocument(name, stream);
    
public org.apache.poi.poifs.filesystem.DocumentEntrycreateDocument(java.lang.String name, int size, org.apache.poi.poifs.filesystem.POIFSWriterListener writer)
create a new DocumentEntry in the root entry; the data will be provided later

param
name the name of the new DocumentEntry
param
size the size of the new DocumentEntry
param
writer the writer of the new DocumentEntry
return
the new DocumentEntry
exception
IOException

        return getRoot().createDocument(name, size, writer);
    
public org.apache.poi.poifs.filesystem.DocumentInputStreamcreateDocumentInputStream(java.lang.String documentName)
open a document in the root entry's list of entries

param
documentName the name of the document to be opened
return
a newly opened DocumentInputStream
exception
IOException if the document does not exist or the name is that of a DirectoryEntry

        Entry document = getRoot().getEntry(documentName);

        if (!document.isDocumentEntry())
        {
            throw new IOException("Entry '" + documentName
                                  + "' is not a DocumentEntry");
        }
        return new DocumentInputStream(( DocumentEntry ) document);
    
public org.apache.poi.poifs.filesystem.DirectoryEntrygetRoot()
get the root entry

return
the root entry

        if (_root == null)
        {
            _root = new DirectoryNode(_property_table.getRoot(), this, null);
        }
        return _root;
    
public java.lang.StringgetShortDescription()
Provides a short description of the object, to be used when a POIFSViewable object has not provided its contents.

return
short description

        return "POIFS FileSystem";
    
public java.lang.Object[]getViewableArray()
Get an array of objects, some of which may implement POIFSViewable

return
an array of Object; may not be null, but may be empty

        if (preferArray())
        {
            return (( POIFSViewable ) getRoot()).getViewableArray();
        }
        else
        {
            return new Object[ 0 ];
        }
    
public java.util.IteratorgetViewableIterator()
Get an Iterator of objects, some of which may implement POIFSViewable

return
an Iterator; may not be null, but may have an empty back end store

        if (!preferArray())
        {
            return (( POIFSViewable ) getRoot()).getViewableIterator();
        }
        else
        {
            return Collections.EMPTY_LIST.iterator();
        }
    
public static voidmain(java.lang.String[] args)
read in a file and write it back out again

param
args names of the files; arg[ 0 ] is the input file, arg[ 1 ] is the output file
exception
IOException

        if (args.length != 2)
        {
            System.err.println(
                "two arguments required: input filename and output filename");
            System.exit(1);
        }
        FileInputStream  istream = new FileInputStream(args[ 0 ]);
        FileOutputStream ostream = new FileOutputStream(args[ 1 ]);

        new POIFSFileSystem(istream).writeFilesystem(ostream);
        istream.close();
        ostream.close();
    
public booleanpreferArray()
Give viewers a hint as to whether to call getViewableArray or getViewableIterator

return
true if a viewer should call getViewableArray, false if a viewer should call getViewableIterator

        return (( POIFSViewable ) getRoot()).preferArray();
    
private voidprocessProperties(org.apache.poi.poifs.storage.BlockList small_blocks, org.apache.poi.poifs.storage.BlockList big_blocks, java.util.Iterator properties, org.apache.poi.poifs.filesystem.DirectoryNode dir)

        while (properties.hasNext())
        {
            Property      property = ( Property ) properties.next();
            String        name     = property.getName();
            DirectoryNode parent   = (dir == null)
                                     ? (( DirectoryNode ) getRoot())
                                     : dir;

            if (property.isDirectory())
            {
                DirectoryNode new_dir =
                    ( DirectoryNode ) parent.createDirectory(name);

                new_dir.setStorageClsid( property.getStorageClsid() );

                processProperties(
                    small_blocks, big_blocks,
                    (( DirectoryProperty ) property).getChildren(), new_dir);
            }
            else
            {
                int           startBlock = property.getStartBlock();
                int           size       = property.getSize();
                POIFSDocument document   = null;

                if (property.shouldUseSmallBlocks())
                {
                    document =
                        new POIFSDocument(name, small_blocks
                            .fetchBlocks(startBlock), size);
                }
                else
                {
                    document =
                        new POIFSDocument(name,
                                          big_blocks.fetchBlocks(startBlock),
                                          size);
                }
                parent.createDocument(document);
            }
        }
    
voidremove(org.apache.poi.poifs.filesystem.EntryNode entry)
remove an entry

param
entry to be removed

        _property_table.removeProperty(entry.getProperty());
        if (entry.isDocumentEntry())
        {
            _documents.remove((( DocumentNode ) entry).getDocument());
        }
    
public voidwriteFilesystem(java.io.OutputStream stream)
Write the filesystem out

param
stream the OutputStream to which the filesystem will be written
exception
IOException thrown on errors writing to the stream


        // get the property table ready
        _property_table.preWrite();

        // create the small block store, and the SBAT
        SmallBlockTableWriter      sbtw       =
            new SmallBlockTableWriter(_documents, _property_table.getRoot());

        // create the block allocation table
        BlockAllocationTableWriter bat        =
            new BlockAllocationTableWriter();

        // create a list of BATManaged objects: the documents plus the
        // property table and the small block table
        List                       bm_objects = new ArrayList();

        bm_objects.addAll(_documents);
        bm_objects.add(_property_table);
        bm_objects.add(sbtw);
        bm_objects.add(sbtw.getSBAT());

        // walk the list, allocating space for each and assigning each
        // a starting block number
        Iterator iter = bm_objects.iterator();

        while (iter.hasNext())
        {
            BATManaged bmo         = ( BATManaged ) iter.next();
            int        block_count = bmo.countBlocks();

            if (block_count != 0)
            {
                bmo.setStartBlock(bat.allocateSpace(block_count));
            }
            else
            {

                // Either the BATManaged object is empty or its data
                // is composed of SmallBlocks; in either case,
                // allocating space in the BAT is inappropriate
            }
        }

        // allocate space for the block allocation table and take its
        // starting block
        int               batStartBlock       = bat.createBlocks();

        // get the extended block allocation table blocks
        HeaderBlockWriter header_block_writer = new HeaderBlockWriter();
        BATBlock[]        xbat_blocks         =
            header_block_writer.setBATBlocks(bat.countBlocks(),
                                             batStartBlock);

        // set the property table start block
        header_block_writer.setPropertyStart(_property_table.getStartBlock());

        // set the small block allocation table start block
        header_block_writer.setSBATStart(sbtw.getSBAT().getStartBlock());

        // set the small block allocation table block count
        header_block_writer.setSBATBlockCount(sbtw.getSBATBlockCount());

        // the header is now properly initialized. Make a list of
        // writers (the header block, followed by the documents, the
        // property table, the small block store, the small block
        // allocation table, the block allocation table, and the
        // extended block allocation table blocks)
        List writers = new ArrayList();

        writers.add(header_block_writer);
        writers.addAll(_documents);
        writers.add(_property_table);
        writers.add(sbtw);
        writers.add(sbtw.getSBAT());
        writers.add(bat);
        for (int j = 0; j < xbat_blocks.length; j++)
        {
            writers.add(xbat_blocks[ j ]);
        }

        // now, write everything out
        iter = writers.iterator();
        while (iter.hasNext())
        {
            BlockWritable writer = ( BlockWritable ) iter.next();

            writer.writeBlocks(stream);
        }