You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2008/10/24 07:46:29 UTC

svn commit: r707551 - /poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java

Author: josh
Date: Thu Oct 23 22:46:29 2008
New Revision: 707551

URL: http://svn.apache.org/viewvc?rev=707551&view=rev
Log:
Simplification and code clean-up

Modified:
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java?rev=707551&r1=707550&r2=707551&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/POIFSDocument.java Thu Oct 23 22:46:29 2008
@@ -1,4 +1,3 @@
-
 /* ====================================================================
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,21 +14,25 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
 
 package org.apache.poi.poifs.filesystem;
 
-import java.io.*;
-
-import java.util.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 
 import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.dev.POIFSViewable;
 import org.apache.poi.poifs.property.DocumentProperty;
 import org.apache.poi.poifs.property.Property;
 import org.apache.poi.poifs.storage.BlockWritable;
-import org.apache.poi.poifs.storage.ListManagedBlock;
 import org.apache.poi.poifs.storage.DocumentBlock;
+import org.apache.poi.poifs.storage.ListManagedBlock;
 import org.apache.poi.poifs.storage.RawDataBlock;
 import org.apache.poi.poifs.storage.SmallDocumentBlock;
 import org.apache.poi.util.HexDump;
@@ -39,595 +42,438 @@
  *
  * @author Marc Johnson (mjohnson at apache dot org)
  */
-
-public class POIFSDocument
-    implements BATManaged, BlockWritable, POIFSViewable
-{
-    private DocumentProperty _property;
-    private int              _size;
-
-    // one of these stores will be valid
-    private SmallBlockStore  _small_store;
-    private BigBlockStore    _big_store;
-
-    /**
-     * Constructor from large blocks
-     *
-     * @param name the name of the POIFSDocument
-     * @param blocks the big blocks making up the POIFSDocument
-     * @param length the actual length of the POIFSDocument
-     *
-     * @exception IOException
-     */
-
-    public POIFSDocument(final String name, final RawDataBlock [] blocks,
-                         final int length)
-        throws IOException
-    {
-        _size        = length;
-        _big_store   = new BigBlockStore(blocks);
-        _property    = new DocumentProperty(name, _size);
-        _small_store = new SmallBlockStore(new BlockWritable[ 0 ]);
-        _property.setDocument(this);
-    }
-
-    /**
-     * Constructor from small blocks
-     *
-     * @param name the name of the POIFSDocument
-     * @param blocks the small blocks making up the POIFSDocument
-     * @param length the actual length of the POIFSDocument
-     */
-
-    public POIFSDocument(final String name,
-                         final SmallDocumentBlock [] blocks, final int length)
-    {
-        _size = length;
-        try
-        {
-            _big_store = new BigBlockStore(new RawDataBlock[ 0 ]);
-        }
-        catch (IOException ignored)
-        {
-
-            // can't happen with that constructor
-        }
-        _property    = new DocumentProperty(name, _size);
-        _small_store = new SmallBlockStore(blocks);
-        _property.setDocument(this);
-    }
-
-    /**
-     * Constructor from small blocks
-     *
-     * @param name the name of the POIFSDocument
-     * @param blocks the small blocks making up the POIFSDocument
-     * @param length the actual length of the POIFSDocument
-     *
-     * @exception IOException
-     */
-
-    public POIFSDocument(final String name, final ListManagedBlock [] blocks,
-                         final int length)
-        throws IOException
-    {
-        _size     = length;
-        _property = new DocumentProperty(name, _size);
-        _property.setDocument(this);
-        if (Property.isSmall(_size))
-        {
-            _big_store   = new BigBlockStore(new RawDataBlock[ 0 ]);
-            _small_store = new SmallBlockStore(blocks);
-        }
-        else
-        {
-            _big_store   = new BigBlockStore(blocks);
-            _small_store = new SmallBlockStore(new BlockWritable[ 0 ]);
-        }
-    }
-
-    /**
-     * Constructor
-     *
-     * @param name the name of the POIFSDocument
-     * @param stream the InputStream we read data from
-     *
-     * @exception IOException thrown on read errors
-     */
-
-    public POIFSDocument(final String name, final InputStream stream)
-        throws IOException
-    {
-        List blocks = new ArrayList();
-
-        _size = 0;
-        while (true)
-        {
-            DocumentBlock block     = new DocumentBlock(stream);
-            int           blockSize = block.size();
-
-            if (blockSize > 0)
-            {
-                blocks.add(block);
-                _size += blockSize;
-            }
-            if (block.partiallyRead())
-            {
-                break;
-            }
-        }
-        DocumentBlock[] bigBlocks =
-            ( DocumentBlock [] ) blocks.toArray(new DocumentBlock[ 0 ]);
-
-        _big_store = new BigBlockStore(bigBlocks);
-        _property  = new DocumentProperty(name, _size);
-        _property.setDocument(this);
-        if (_property.shouldUseSmallBlocks())
-        {
-            _small_store =
-                new SmallBlockStore(SmallDocumentBlock.convert(bigBlocks,
-                    _size));
-            _big_store   = new BigBlockStore(new DocumentBlock[ 0 ]);
-        }
-        else
-        {
-            _small_store = new SmallBlockStore(new BlockWritable[ 0 ]);
-        }
-    }
-
-    /**
-     * Constructor
-     *
-     * @param name the name of the POIFSDocument
-     * @param size the length of the POIFSDocument
-     * @param path the path of the POIFSDocument
-     * @param writer the writer who will eventually write the document
-     *               contents
-     *
-     * @exception IOException thrown on read errors
-     */
-
-    public POIFSDocument(final String name, final int size,
-                         final POIFSDocumentPath path,
-                         final POIFSWriterListener writer)
-        throws IOException
-    {
-        _size     = size;
-        _property = new DocumentProperty(name, _size);
-        _property.setDocument(this);
-        if (_property.shouldUseSmallBlocks())
-        {
-            _small_store = new SmallBlockStore(path, name, size, writer);
-            _big_store   = new BigBlockStore(new Object[ 0 ]);
-        }
-        else
-        {
-            _small_store = new SmallBlockStore(new BlockWritable[ 0 ]);
-            _big_store   = new BigBlockStore(path, name, size, writer);
-        }
-    }
-
-    /**
-     * return the array of SmallDocumentBlocks used
-     *
-     * @return array of SmallDocumentBlocks; may be empty, cannot be null
-     */
-
-    public BlockWritable [] getSmallBlocks()
-    {
-        return _small_store.getBlocks();
-    }
-
-    /**
-     * @return size of the document
-     */
-
-    public int getSize()
-    {
-        return _size;
-    }
-
-    /**
-     * read data from the internal stores
-     *
-     * @param buffer the buffer to write to
-     * @param offset the offset into our storage to read from
-     */
-
-    void read(final byte [] buffer, final int offset)
-    {
-        if (_property.shouldUseSmallBlocks())
-        {
-            SmallDocumentBlock.read(_small_store.getBlocks(), buffer, offset);
-        }
-        else
-        {
-            DocumentBlock.read(_big_store.getBlocks(), buffer, offset);
-        }
-    }
-
-    /**
-     * Get the DocumentProperty
-     *
-     * @return the instance's DocumentProperty
-     */
-
-    DocumentProperty getDocumentProperty()
-    {
-        return _property;
-    }
-
-    /* ********** START implementation of BlockWritable ********** */
-
-    /**
-     * Write the storage to an OutputStream
-     *
-     * @param stream the OutputStream to which the stored data should
-     *               be written
-     *
-     * @exception IOException on problems writing to the specified
-     *            stream
-     */
-
-    public void writeBlocks(final OutputStream stream)
-        throws IOException
-    {
-        _big_store.writeBlocks(stream);
-    }
-
-    /* **********  END  implementation of BlockWritable ********** */
-    /* ********** START implementation of BATManaged ********** */
-
-    /**
-     * Return the number of BigBlock's this instance uses
-     *
-     * @return count of BigBlock instances
-     */
-
-    public int countBlocks()
-    {
-        return _big_store.countBlocks();
-    }
-
-    /**
-     * Set the start block for this instance
-     *
-     * @param index index into the array of blocks making up the
-     *        filesystem
-     */
-
-    public void setStartBlock(final int index)
-    {
-        _property.setStartBlock(index);
-    }
-
-    /* **********  END  implementation of BATManaged ********** */
-    /* ********** START begin implementation of POIFSViewable ********** */
-
-    /**
-     * Get an array of objects, some of which may implement
-     * POIFSViewable
-     *
-     * @return an array of Object; may not be null, but may be empty
-     */
-
-    public Object [] getViewableArray()
-    {
-        Object[] results = new Object[ 1 ];
-        String   result;
-
-        try
-        {
-            ByteArrayOutputStream output = new ByteArrayOutputStream();
-            BlockWritable[]       blocks = null;
-
-            if (_big_store.isValid())
-            {
-                blocks = _big_store.getBlocks();
-            }
-            else if (_small_store.isValid())
-            {
-                blocks = _small_store.getBlocks();
-            }
-            if (blocks != null)
-            {
-                for (int k = 0; k < blocks.length; k++)
-                {
-                    blocks[ k ].writeBlocks(output);
-                }
-                byte[] data = output.toByteArray();
-
-                if (data.length > _property.getSize())
-                {
-                    byte[] tmp = new byte[ _property.getSize() ];
-
-                    System.arraycopy(data, 0, tmp, 0, tmp.length);
-                    data = tmp;
-                }
-                output = new ByteArrayOutputStream();
-                HexDump.dump(data, 0, output, 0);
-                result = output.toString();
-            }
-            else
-            {
-                result = "<NO DATA>";
-            }
-        }
-        catch (IOException e)
-        {
-            result = e.getMessage();
-        }
-        results[ 0 ] = result;
-        return results;
-    }
-
-    /**
-     * 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
-     */
-
-    public Iterator getViewableIterator()
-    {
-        return Collections.EMPTY_LIST.iterator();
-    }
-
-    /**
-     * 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
-     */
-
-    public boolean preferArray()
-    {
-        return true;
-    }
-
-    /**
-     * Provides a short description of the object, to be used when a
-     * POIFSViewable object has not provided its contents.
-     *
-     * @return short description
-     */
-
-    public String getShortDescription()
-    {
-        StringBuffer buffer = new StringBuffer();
-
-        buffer.append("Document: \"").append(_property.getName())
-            .append("\"");
-        buffer.append(" size = ").append(getSize());
-        return buffer.toString();
-    }
-
-    /* **********  END  begin implementation of POIFSViewable ********** */
-    private class SmallBlockStore
-    {
-        private SmallDocumentBlock[] smallBlocks;
-        private POIFSDocumentPath    path;
-        private String               name;
-        private int                  size;
-        private POIFSWriterListener  writer;
-
-        /**
-         * Constructor
-         *
-         * @param blocks blocks to construct the store from
-         */
-
-        SmallBlockStore(final Object [] blocks)
-        {
-            smallBlocks = new SmallDocumentBlock[ blocks.length ];
-            for (int j = 0; j < blocks.length; j++)
-            {
-                smallBlocks[ j ] = ( SmallDocumentBlock ) blocks[ j ];
-            }
-            this.path   = null;
-            this.name   = null;
-            this.size   = -1;
-            this.writer = null;
-        }
-
-        /**
-         * Constructor for a small block store that will be written
-         * later
-         *
-         * @param path path of the document
-         * @param name name of the document
-         * @param size length of the document
-         * @param writer the object that will eventually write the document
-         */
-
-        SmallBlockStore(final POIFSDocumentPath path, final String name,
-                        final int size, final POIFSWriterListener writer)
-        {
-            smallBlocks = new SmallDocumentBlock[ 0 ];
-            this.path   = path;
-            this.name   = name;
-            this.size   = size;
-            this.writer = writer;
-        }
-
-        /**
-         * @return true if this store is a valid source of data
-         */
-
-        boolean isValid()
-        {
-            return ((smallBlocks.length > 0) || (writer != null));
-        }
-
-        /**
-         * @return the SmallDocumentBlocks
-         */
-
-        BlockWritable [] getBlocks()
-        {
-            if (isValid() && (writer != null))
-            {
-                ByteArrayOutputStream stream  =
-                    new ByteArrayOutputStream(size);
-                DocumentOutputStream  dstream =
-                    new DocumentOutputStream(stream, size);
-
-                writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream,
-                        path, name, size));
-                smallBlocks = SmallDocumentBlock.convert(stream.toByteArray(),
-                                                         size);
-            }
-            return smallBlocks;
-        }
-    }   // end private class SmallBlockStore
-
-    private class BigBlockStore
-    {
-        private DocumentBlock[]     bigBlocks;
-        private POIFSDocumentPath   path;
-        private String              name;
-        private int                 size;
-        private POIFSWriterListener writer;
-
-        /**
-         * Constructor
-         *
-         * @param blocks the blocks making up the store
-         *
-         * @exception IOException on I/O error
-         */
-
-        BigBlockStore(final Object [] blocks)
-            throws IOException
-        {
-            bigBlocks = new DocumentBlock[ blocks.length ];
-            for (int j = 0; j < blocks.length; j++)
-            {
-                if (blocks[ j ] instanceof DocumentBlock)
-                {
-                    bigBlocks[ j ] = ( DocumentBlock ) blocks[ j ];
-                }
-                else
-                {
-                    bigBlocks[ j ] =
-                        new DocumentBlock(( RawDataBlock ) blocks[ j ]);
-                }
-            }
-            this.path   = null;
-            this.name   = null;
-            this.size   = -1;
-            this.writer = null;
-        }
-
-        /**
-         * Constructor for a big block store that will be written
-         * later
-         *
-         * @param path path of the document
-         * @param name name of the document
-         * @param size length of the document
-         * @param writer the object that will eventually write the
-         *               document
-         */
-
-        BigBlockStore(final POIFSDocumentPath path, final String name,
-                      final int size, final POIFSWriterListener writer)
-        {
-            bigBlocks   = new DocumentBlock[ 0 ];
-            this.path   = path;
-            this.name   = name;
-            this.size   = size;
-            this.writer = writer;
-        }
-
-        /**
-         * @return true if this store is a valid source of data
-         */
-
-        boolean isValid()
-        {
-            return ((bigBlocks.length > 0) || (writer != null));
-        }
-
-        /**
-         * @return the DocumentBlocks
-         */
-
-        DocumentBlock [] getBlocks()
-        {
-            if (isValid() && (writer != null))
-            {
-                ByteArrayOutputStream stream  =
-                    new ByteArrayOutputStream(size);
-                DocumentOutputStream  dstream =
-                    new DocumentOutputStream(stream, size);
-
-                writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream,
-                        path, name, size));
-                bigBlocks = DocumentBlock.convert(stream.toByteArray(), size);
-            }
-            return bigBlocks;
-        }
-
-        /**
-         * write the blocks to a stream
-         *
-         * @param stream the stream to which the data is to be written
-         *
-         * @exception IOException on error
-         */
-
-        void writeBlocks(OutputStream stream)
-            throws IOException
-        {
-            if (isValid())
-            {
-                if (writer != null)
-                {
-                    DocumentOutputStream dstream =
-                        new DocumentOutputStream(stream, size);
-
-                    writer.processPOIFSWriterEvent(
-                        new POIFSWriterEvent(dstream, path, name, size));
-                    dstream.writeFiller(countBlocks()
-                                        * POIFSConstants
-                                            .BIG_BLOCK_SIZE, DocumentBlock
-                                            .getFillByte());
-                }
-                else
-                {
-                    for (int k = 0; k < bigBlocks.length; k++)
-                    {
-                        bigBlocks[ k ].writeBlocks(stream);
-                    }
-                }
-            }
-        }
-
-        /**
-         * @return number of big blocks making up this document
-         */
-
-        int countBlocks()
-        {
-            int rval = 0;
-
-            if (isValid())
-            {
-                if (writer != null)
-                {
-                    rval = (size + POIFSConstants.BIG_BLOCK_SIZE - 1)
-                           / POIFSConstants.BIG_BLOCK_SIZE;
-                }
-                else
-                {
-                    rval = bigBlocks.length;
-                }
-            }
-            return rval;
-        }
-    }   // end private class BigBlockStore
-}       // end class POIFSDocument
-
+public final class POIFSDocument implements BATManaged, BlockWritable, POIFSViewable  {
+	private static final DocumentBlock[] EMPTY_BIG_BLOCK_ARRAY = { };
+	private static final SmallDocumentBlock[] EMPTY_SMALL_BLOCK_ARRAY = { };
+	private DocumentProperty _property;
+	private int _size;
+
+	// one of these stores will be valid
+	private SmallBlockStore  _small_store;
+	private BigBlockStore	_big_store;
+
+	/**
+	 * Constructor from large blocks
+	 *
+	 * @param name the name of the POIFSDocument
+	 * @param blocks the big blocks making up the POIFSDocument
+	 * @param length the actual length of the POIFSDocument
+	 */
+	public POIFSDocument(String name, RawDataBlock[] blocks, int length) throws IOException {
+		_size = length;
+		_big_store = new BigBlockStore(convertRawBlocksToBigBlocks(blocks));
+		_property = new DocumentProperty(name, _size);
+		_small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY);
+		_property.setDocument(this);
+	}
+
+	// TODO - awkward typing going on here
+	private static DocumentBlock[] convertRawBlocksToBigBlocks(ListManagedBlock[] blocks) throws IOException {
+		DocumentBlock[] result = new DocumentBlock[blocks.length];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = new DocumentBlock((RawDataBlock)blocks[i]); 
+		}
+		return result;
+	}
+	private static SmallDocumentBlock[] convertRawBlocksToSmallBlocks(ListManagedBlock[] blocks) {
+		if (blocks instanceof SmallDocumentBlock[]) {
+			return (SmallDocumentBlock[]) blocks;
+		}
+		SmallDocumentBlock[] result = new SmallDocumentBlock[blocks.length];
+		System.arraycopy(blocks, 0, result, 0, blocks.length);
+		return result;
+	}
+
+	/**
+	 * Constructor from small blocks
+	 *
+	 * @param name the name of the POIFSDocument
+	 * @param blocks the small blocks making up the POIFSDocument
+	 * @param length the actual length of the POIFSDocument
+	 */
+	public POIFSDocument(String name, SmallDocumentBlock[] blocks, int length) {
+		_size = length;
+		_big_store = new BigBlockStore(EMPTY_BIG_BLOCK_ARRAY);
+		_property = new DocumentProperty(name, _size);
+		_small_store = new SmallBlockStore(blocks);
+		_property.setDocument(this);
+	}
+
+	/**
+	 * Constructor from small blocks
+	 *
+	 * @param name the name of the POIFSDocument
+	 * @param blocks the small blocks making up the POIFSDocument
+	 * @param length the actual length of the POIFSDocument
+	 */
+	public POIFSDocument(String name, ListManagedBlock[] blocks, int length) throws IOException {
+		_size = length;
+		_property = new DocumentProperty(name, _size);
+		_property.setDocument(this);
+		if (Property.isSmall(_size)) {
+			_big_store = new BigBlockStore(EMPTY_BIG_BLOCK_ARRAY);
+			_small_store = new SmallBlockStore(convertRawBlocksToSmallBlocks(blocks));
+		} else {
+			_big_store = new BigBlockStore(convertRawBlocksToBigBlocks(blocks));
+			_small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY);
+		}
+	}
+
+	/**
+	 * Constructor
+	 *
+	 * @param name the name of the POIFSDocument
+	 * @param stream the InputStream we read data from
+	 */
+	public POIFSDocument(String name, InputStream stream) throws IOException {
+		List blocks = new ArrayList();
+
+		_size = 0;
+		while (true) {
+			DocumentBlock block = new DocumentBlock(stream);
+			int blockSize = block.size();
+
+			if (blockSize > 0) {
+				blocks.add(block);
+				_size += blockSize;
+			}
+			if (block.partiallyRead()) {
+				break;
+			}
+		}
+		DocumentBlock[] bigBlocks = (DocumentBlock[]) blocks.toArray(new DocumentBlock[blocks.size()]);
+
+		_big_store = new BigBlockStore(bigBlocks);
+		_property = new DocumentProperty(name, _size);
+		_property.setDocument(this);
+		if (_property.shouldUseSmallBlocks()) {
+			_small_store = new SmallBlockStore(SmallDocumentBlock.convert(bigBlocks, _size));
+			_big_store = new BigBlockStore(new DocumentBlock[0]);
+		} else {
+			_small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY);
+		}
+	}
+
+	/**
+	 * Constructor
+	 *
+	 * @param name the name of the POIFSDocument
+	 * @param size the length of the POIFSDocument
+	 * @param path the path of the POIFSDocument
+	 * @param writer the writer who will eventually write the document contents
+	 */
+	public POIFSDocument(String name, int size, POIFSDocumentPath path, POIFSWriterListener writer) {
+		_size = size;
+		_property = new DocumentProperty(name, _size);
+		_property.setDocument(this);
+		if (_property.shouldUseSmallBlocks()) {
+			_small_store = new SmallBlockStore(path, name, size, writer);
+			_big_store = new BigBlockStore(EMPTY_BIG_BLOCK_ARRAY);
+		} else {
+			_small_store = new SmallBlockStore(EMPTY_SMALL_BLOCK_ARRAY);
+			_big_store = new BigBlockStore(path, name, size, writer);
+		}
+	}
+
+	/**
+	 * @return array of SmallDocumentBlocks; may be empty, cannot be null
+	 */
+	public BlockWritable[] getSmallBlocks() {
+		return _small_store.getBlocks();
+	}
+
+	/**
+	 * @return size of the document
+	 */
+	public int getSize() {
+		return _size;
+	}
+
+	/**
+	 * read data from the internal stores
+	 *
+	 * @param buffer the buffer to write to
+	 * @param offset the offset into our storage to read from
+	 */
+	void read(byte[] buffer, int offset) {
+		if (_property.shouldUseSmallBlocks()) {
+			SmallDocumentBlock.read(_small_store.getBlocks(), buffer, offset);
+		} else {
+			DocumentBlock.read(_big_store.getBlocks(), buffer, offset);
+		}
+	}
+
+	/**
+	 * @return the instance's DocumentProperty
+	 */
+
+	DocumentProperty getDocumentProperty() {
+		return _property;
+	}
+
+	/* ********** START implementation of BlockWritable ********** */
+
+	/**
+	 * Write the storage to an OutputStream
+	 *
+	 * @param stream the OutputStream to which the stored data should be written
+	 */
+	public void writeBlocks(OutputStream stream) throws IOException {
+		_big_store.writeBlocks(stream);
+	}
+
+	/* **********  END  implementation of BlockWritable ********** */
+	/* ********** START implementation of BATManaged ********** */
+
+	/**
+	 * Return the number of BigBlock's this instance uses
+	 *
+	 * @return count of BigBlock instances
+	 */
+	public int countBlocks() {
+		return _big_store.countBlocks();
+	}
+
+	/**
+	 * Set the start block for this instance
+	 *
+	 * @param index index into the array of blocks making up the filesystem
+	 */
+	public void setStartBlock(int index) {
+		_property.setStartBlock(index);
+	}
+
+	/* **********  END  implementation of BATManaged ********** */
+	/* ********** START begin implementation of POIFSViewable ********** */
+
+	/**
+	 * Get an array of objects, some of which may implement POIFSViewable
+	 *
+	 * @return an array of Object; may not be null, but may be empty
+	 */
+	public Object[] getViewableArray() {
+		Object[] results = new Object[1];
+		String result;
+
+		try {
+			ByteArrayOutputStream output = new ByteArrayOutputStream();
+			BlockWritable[] blocks = null;
+
+			if (_big_store.isValid()) {
+				blocks = _big_store.getBlocks();
+			} else if (_small_store.isValid()) {
+				blocks = _small_store.getBlocks();
+			}
+			if (blocks != null) {
+				for (int k = 0; k < blocks.length; k++) {
+					blocks[k].writeBlocks(output);
+				}
+				byte[] data = output.toByteArray();
+
+				if (data.length > _property.getSize()) {
+					byte[] tmp = new byte[_property.getSize()];
+
+					System.arraycopy(data, 0, tmp, 0, tmp.length);
+					data = tmp;
+				}
+				output = new ByteArrayOutputStream();
+				HexDump.dump(data, 0, output, 0);
+				result = output.toString();
+			} else {
+				result = "<NO DATA>";
+			}
+		} catch (IOException e) {
+			result = e.getMessage();
+		}
+		results[0] = result;
+		return results;
+	}
+
+	/**
+	 * 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
+	 */
+	public Iterator getViewableIterator() {
+		return Collections.EMPTY_LIST.iterator();
+	}
+
+	/**
+	 * Give viewers a hint as to whether to call getViewableArray or
+	 * getViewableIterator
+	 *
+	 * @return <code>true</code> if a viewer should call getViewableArray,
+	 *		 <code>false</code> if a viewer should call getViewableIterator
+	 */
+	public boolean preferArray() {
+		return true;
+	}
+
+	/**
+	 * Provides a short description of the object, to be used when a
+	 * POIFSViewable object has not provided its contents.
+	 *
+	 * @return short description
+	 */
+	public String getShortDescription() {
+		StringBuffer buffer = new StringBuffer();
+
+		buffer.append("Document: \"").append(_property.getName()).append("\"");
+		buffer.append(" size = ").append(getSize());
+		return buffer.toString();
+	}
+
+	/* **********  END  begin implementation of POIFSViewable ********** */
+	private static final class SmallBlockStore {
+		private SmallDocumentBlock[] smallBlocks;
+		private final POIFSDocumentPath path;
+		private final String name;
+		private final int size;
+		private final POIFSWriterListener writer;
+
+		/**
+		 * Constructor
+		 *
+		 * @param blocks blocks to construct the store from
+		 */
+		SmallBlockStore(SmallDocumentBlock[] blocks) {
+			smallBlocks = (SmallDocumentBlock[]) blocks.clone();
+			this.path = null;
+			this.name = null;
+			this.size = -1;
+			this.writer = null;
+		}
+
+		/**
+		 * Constructor for a small block store that will be written later
+		 *
+		 * @param path path of the document
+		 * @param name name of the document
+		 * @param size length of the document
+		 * @param writer the object that will eventually write the document
+		 */
+		SmallBlockStore(POIFSDocumentPath path, String name, int size, POIFSWriterListener writer) {
+			smallBlocks = new SmallDocumentBlock[0];
+			this.path = path;
+			this.name = name;
+			this.size = size;
+			this.writer = writer;
+		}
+
+		/**
+		 * @return <code>true</code> if this store is a valid source of data
+		 */
+		boolean isValid() {
+			return smallBlocks.length > 0 || writer != null;
+		}
+
+		/**
+		 * @return the SmallDocumentBlocks
+		 */
+		SmallDocumentBlock[] getBlocks() {
+			if (isValid() && writer != null) {
+				ByteArrayOutputStream stream = new ByteArrayOutputStream(size);
+				DocumentOutputStream dstream = new DocumentOutputStream(stream, size);
+
+				writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, path, name, size));
+				smallBlocks = SmallDocumentBlock.convert(stream.toByteArray(), size);
+			}
+			return smallBlocks;
+		}
+	} // end private class SmallBlockStore
+
+	private static final class BigBlockStore {
+		private DocumentBlock[] bigBlocks;
+		private final POIFSDocumentPath path;
+		private final String name;
+		private final int size;
+		private final POIFSWriterListener writer;
+
+		/**
+		 * Constructor
+		 *
+		 * @param blocks the blocks making up the store
+		 */
+		BigBlockStore(DocumentBlock[] blocks) {
+			bigBlocks = (DocumentBlock[]) blocks.clone();
+			this.path = null;
+			this.name = null;
+			this.size = -1;
+			this.writer = null;
+		}
+
+		/**
+		 * Constructor for a big block store that will be written later
+		 *
+		 * @param path path of the document
+		 * @param name name of the document
+		 * @param size length of the document
+		 * @param writer the object that will eventually write the document
+		 */
+		BigBlockStore(POIFSDocumentPath path, String name, int size, POIFSWriterListener writer) {
+			bigBlocks = new DocumentBlock[0];
+			this.path = path;
+			this.name = name;
+			this.size = size;
+			this.writer = writer;
+		}
+
+		/**
+		 * @return <code>true</code> if this store is a valid source of data
+		 */
+		boolean isValid() {
+			return bigBlocks.length > 0 || writer != null;
+		}
+
+		/**
+		 * @return the DocumentBlocks
+		 */
+		DocumentBlock[] getBlocks() {
+			if (isValid() && writer != null) {
+				ByteArrayOutputStream stream = new ByteArrayOutputStream(size);
+				DocumentOutputStream dstream = new DocumentOutputStream(stream, size);
+
+				writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, path, name, size));
+				bigBlocks = DocumentBlock.convert(stream.toByteArray(), size);
+			}
+			return bigBlocks;
+		}
+
+		/**
+		 * write the blocks to a stream
+		 *
+		 * @param stream the stream to which the data is to be written
+		 */
+		void writeBlocks(OutputStream stream) throws IOException {
+			if (isValid()) {
+				if (writer != null) {
+					DocumentOutputStream dstream = new DocumentOutputStream(stream, size);
+
+					writer.processPOIFSWriterEvent(new POIFSWriterEvent(dstream, path, name, size));
+					dstream.writeFiller(countBlocks() * POIFSConstants.BIG_BLOCK_SIZE,
+							DocumentBlock.getFillByte());
+				} else {
+					for (int k = 0; k < bigBlocks.length; k++) {
+						bigBlocks[k].writeBlocks(stream);
+					}
+				}
+			}
+		}
+
+		/**
+		 * @return number of big blocks making up this document
+		 */
+		int countBlocks() {
+
+			if (isValid()) {
+				if (writer == null) {
+					return bigBlocks.length;
+				}
+				return (size + POIFSConstants.BIG_BLOCK_SIZE - 1)
+							/ POIFSConstants.BIG_BLOCK_SIZE;
+			}
+			return 0;
+		}
+	} // end private class BigBlockStore
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org