diff options
14 files changed, 222 insertions, 275 deletions
diff --git a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java index 8a416cdb7b..ab4eeac311 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/ValueRecordsAggregate.java @@ -18,6 +18,7 @@ package org.apache.poi.hssf.record.aggregates; import java.util.Iterator; +import java.util.NoSuchElementException; import org.apache.poi.hssf.model.RecordStream; import org.apache.poi.hssf.record.BlankRecord; @@ -338,8 +339,9 @@ public final class ValueRecordsAggregate implements Iterable<CellValueRecordInte } public CellValueRecordInterface next() { - if (!hasNext()) - throw new IndexOutOfBoundsException("iterator has no next"); + if (!hasNext()) { + throw new NoSuchElementException(); + } curRowIndex = nextRowIndex; curColIndex = nextColIndex; diff --git a/src/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java b/src/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java index 568b373761..717247c5b6 100644 --- a/src/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java +++ b/src/java/org/apache/poi/poifs/filesystem/FilteringDirectoryNode.java @@ -29,6 +29,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Set; import org.apache.poi.hpsf.ClassID; @@ -37,7 +38,7 @@ import org.apache.poi.hpsf.ClassID; * A DirectoryEntry filter, which exposes another * DirectoryEntry less certain parts. * This is typically used when copying or comparing - * Filesystems. + * Filesystems. */ public class FilteringDirectoryNode implements DirectoryEntry { @@ -49,14 +50,14 @@ public class FilteringDirectoryNode implements DirectoryEntry * Excludes of our child directories */ private Map<String,List<String>> childExcludes; - + private DirectoryEntry directory; - + /** * Creates a filter round the specified directory, which * will exclude entries such as "MyNode" and "MyDir/IgnoreNode". * The excludes can stretch into children, if they contain a /. - * + * * @param directory The Directory to filter * @param excludes The Entries to exclude * @throws IllegalArgumentException if directory is null @@ -66,7 +67,7 @@ public class FilteringDirectoryNode implements DirectoryEntry throw new IllegalArgumentException("directory cannot be null"); } this.directory = directory; - + // Process the excludes this.excludes = new HashSet<>(); this.childExcludes = new HashMap<>(); @@ -108,7 +109,7 @@ public class FilteringDirectoryNode implements DirectoryEntry public Iterator<Entry> iterator() { return getEntries(); } - + public int getEntryCount() { int size = directory.getEntryCount(); for (String excl : excludes) { @@ -118,7 +119,7 @@ public class FilteringDirectoryNode implements DirectoryEntry } return size; } - + public Set<String> getEntryNames() { Set<String> names = new HashSet<>(); for (String name : directory.getEntryNames()) { @@ -144,7 +145,7 @@ public class FilteringDirectoryNode implements DirectoryEntry if (excludes.contains(name)) { throw new FileNotFoundException(name); } - + Entry entry = directory.getEntry(name); return wrapEntry(entry); } @@ -152,7 +153,7 @@ public class FilteringDirectoryNode implements DirectoryEntry String name = entry.getName(); if (childExcludes.containsKey(name) && entry instanceof DirectoryEntry) { return new FilteringDirectoryNode( - (DirectoryEntry)entry, childExcludes.get(name)); + (DirectoryEntry)entry, childExcludes.get(name)); } return entry; } @@ -172,7 +173,7 @@ public class FilteringDirectoryNode implements DirectoryEntry public boolean renameTo(String newName) { return directory.renameTo(newName); } - + public String getName() { return directory.getName(); } @@ -188,11 +189,11 @@ public class FilteringDirectoryNode implements DirectoryEntry public boolean isDocumentEntry() { return false; } - + private class FilteringIterator implements Iterator<Entry> { private Iterator<Entry> parent; private Entry next; - + private FilteringIterator() { parent = directory.getEntries(); locateNext(); @@ -207,17 +208,21 @@ public class FilteringDirectoryNode implements DirectoryEntry } } } - + public boolean hasNext() { return (next != null); } - + public Entry next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + Entry e = next; locateNext(); return e; } - + public void remove() { throw new UnsupportedOperationException("Remove not supported"); } diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java b/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java index 0a9465baaa..5bd83cbdf5 100644 --- a/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java +++ b/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.property.RootProperty; @@ -49,10 +50,10 @@ public class POIFSMiniStore extends BlockStore this._sbat_blocks = sbats; this._header = header; this._root = root; - + this._mini_stream = new POIFSStream(filesystem, root.getStartBlock()); } - + /** * Load the block at the given offset. */ @@ -61,18 +62,16 @@ public class POIFSMiniStore extends BlockStore int byteOffset = offset * POIFSConstants.SMALL_BLOCK_SIZE; int bigBlockNumber = byteOffset / _filesystem.getBigBlockSize(); int bigBlockOffset = byteOffset % _filesystem.getBigBlockSize(); - + // Now locate the data block for it Iterator<ByteBuffer> it = _mini_stream.getBlockIterator(); for(int i=0; i<bigBlockNumber; i++) { it.next(); } ByteBuffer dataBlock = it.next(); - if(dataBlock == null) { - throw new IndexOutOfBoundsException("Big block " + bigBlockNumber + " outside stream"); - } + assert(dataBlock != null); - // Position ourselves, and take a slice + // Position ourselves, and take a slice dataBlock.position( dataBlock.position() + bigBlockOffset ); @@ -80,7 +79,7 @@ public class POIFSMiniStore extends BlockStore miniBuffer.limit(POIFSConstants.SMALL_BLOCK_SIZE); return miniBuffer; } - + /** * Load the block, extending the underlying stream if needed */ @@ -89,14 +88,14 @@ public class POIFSMiniStore extends BlockStore if (_mini_stream.getStartBlock() == POIFSConstants.END_OF_CHAIN) { firstInStore = true; } - + // Try to get it without extending the stream if (! firstInStore) { try { return getBlockAt(offset); - } catch(IndexOutOfBoundsException e) {} + } catch(NoSuchElementException e) {} } - + // Need to extend the stream // TODO Replace this with proper append support // For now, do the extending by hand... @@ -104,7 +103,7 @@ public class POIFSMiniStore extends BlockStore // Ask for another block int newBigBlock = _filesystem.getFreeBlock(); _filesystem.createBlockIfNeeded(newBigBlock); - + // If we are the first block to be allocated, initialise the stream if (firstInStore) { _filesystem._get_property_table().getRoot().setStartBlock(newBigBlock); @@ -123,14 +122,14 @@ public class POIFSMiniStore extends BlockStore } _filesystem.setNextBlock(block, newBigBlock); } - + // This is now the new end _filesystem.setNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN); // Now try again, to get the real small block return createBlockIfNeeded(offset); } - + /** * Returns the BATBlock that handles the specified offset, * and the relative index within it @@ -140,7 +139,7 @@ public class POIFSMiniStore extends BlockStore offset, _header, _sbat_blocks ); } - + /** * Works out what block follows the specified one. */ @@ -148,7 +147,7 @@ public class POIFSMiniStore extends BlockStore BATBlockAndIndex bai = getBATBlockAndIndex(offset); return bai.getBlock().getValueAt( bai.getIndex() ); } - + /** * Changes the record of what block follows the specified one. */ @@ -158,7 +157,7 @@ public class POIFSMiniStore extends BlockStore bai.getIndex(), nextBlock ); } - + /** * Finds a free block, and returns its offset. * This method will extend the file if needed, and if doing @@ -166,7 +165,7 @@ public class POIFSMiniStore extends BlockStore */ protected int getFreeBlock() throws IOException { int sectorsPerSBAT = _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock(); - + // First up, do we have any spare ones? int offset = 0; for (BATBlock sbat : _sbat_blocks) { @@ -185,16 +184,16 @@ public class POIFSMiniStore extends BlockStore // Move onto the next SBAT offset += sectorsPerSBAT; } - + // If we get here, then there aren't any // free sectors in any of the SBATs // So, we need to extend the chain and add another - + // Create a new BATBlock BATBlock newSBAT = BATBlock.createEmptyBATBlock(_filesystem.getBigBlockSizeDetails(), false); int batForSBAT = _filesystem.getFreeBlock(); newSBAT.setOurBlockIndex(batForSBAT); - + // Are we the first SBAT? if(_header.getSBATCount() == 0) { // Tell the header that we've got our first SBAT there @@ -212,24 +211,24 @@ public class POIFSMiniStore extends BlockStore } batOffset = nextBat; } - + // Add it in at the end _filesystem.setNextBlock(batOffset, batForSBAT); - + // And update the count _header.setSBATBlockCount( _header.getSBATCount() + 1 ); } - + // Finish allocating _filesystem.setNextBlock(batForSBAT, POIFSConstants.END_OF_CHAIN); _sbat_blocks.add(newSBAT); - + // Return our first spot return offset; } - + @Override protected ChainLoopDetector getChainLoopDetector() { return new ChainLoopDetector( _root.getSize() ); @@ -238,7 +237,7 @@ public class POIFSMiniStore extends BlockStore protected int getBlockStoreBlockSize() { return POIFSConstants.SMALL_BLOCK_SIZE; } - + /** * Writes the SBATs to their backing blocks, and updates * the mini-stream size in the properties. Stream size is diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java b/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java index f5bbf5bd4b..87bd12092d 100644 --- a/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.Iterator; +import java.util.NoSuchElementException; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.BlockStore.ChainLoopDetector; @@ -34,13 +35,13 @@ import org.apache.poi.poifs.storage.HeaderBlock; * {@link POIFSFileSystem}. It can supply an iterator * to read blocks, and way to write out to existing and * new blocks. - * Most users will want a higher level version of this, + * Most users will want a higher level version of this, * which deals with properties to track which stream * this is. * This only works on big block streams, it doesn't * handle small block ones. * This uses the new NIO code - * + * * TODO Implement a streaming write method, and append */ @@ -49,17 +50,17 @@ public class POIFSStream implements Iterable<ByteBuffer> private BlockStore blockStore; private int startBlock; private OutputStream outStream; - + /** * Constructor for an existing stream. It's up to you - * to know how to get the start block (eg from a - * {@link HeaderBlock} or a {@link Property}) + * to know how to get the start block (eg from a + * {@link HeaderBlock} or a {@link Property}) */ public POIFSStream(BlockStore blockStore, int startBlock) { this.blockStore = blockStore; this.startBlock = startBlock; } - + /** * Constructor for a new stream. A start block won't * be allocated until you begin writing to it. @@ -68,7 +69,7 @@ public class POIFSStream implements Iterable<ByteBuffer> this.blockStore = blockStore; this.startBlock = POIFSConstants.END_OF_CHAIN; } - + /** * What block does this stream start at? * Will be {@link POIFSConstants#END_OF_CHAIN} for a @@ -85,7 +86,7 @@ public class POIFSStream implements Iterable<ByteBuffer> public Iterator<ByteBuffer> iterator() { return getBlockIterator(); } - + Iterator<ByteBuffer> getBlockIterator() { if(startBlock == POIFSConstants.END_OF_CHAIN) { throw new IllegalStateException( @@ -113,11 +114,11 @@ public class POIFSStream implements Iterable<ByteBuffer> } return outStream; } - + // TODO Streaming write support // TODO then convert fixed sized write to use streaming internally // TODO Append write support (probably streaming) - + /** * Frees all blocks in the stream */ @@ -135,14 +136,14 @@ public class POIFSStream implements Iterable<ByteBuffer> } this.startBlock = POIFSConstants.END_OF_CHAIN; } - + /** * Class that handles a streaming read of one stream */ protected class StreamBlockByteBufferIterator implements Iterator<ByteBuffer> { private ChainLoopDetector loopDetector; private int nextBlock; - + StreamBlockByteBufferIterator(int firstBlock) { this.nextBlock = firstBlock; try { @@ -157,10 +158,10 @@ public class POIFSStream implements Iterable<ByteBuffer> } public ByteBuffer next() { - if(nextBlock == POIFSConstants.END_OF_CHAIN) { - throw new IndexOutOfBoundsException("Can't read past the end of the stream"); + if (!hasNext()) { + throw new NoSuchElementException("Can't read past the end of the stream"); } - + try { loopDetector.claim(nextBlock); ByteBuffer data = blockStore.getBlockAt(nextBlock); @@ -175,7 +176,7 @@ public class POIFSStream implements Iterable<ByteBuffer> throw new UnsupportedOperationException(); } } - + protected class StreamBlockByteBuffer extends OutputStream { byte[] oneByte = new byte[1]; ByteBuffer buffer; @@ -192,25 +193,25 @@ public class POIFSStream implements Iterable<ByteBuffer> void createBlockIfNeeded() throws IOException { if (buffer != null && buffer.hasRemaining()) return; - + int thisBlock = nextBlock; - + // Allocate a block if needed, otherwise figure // out what the next block will be if(thisBlock == POIFSConstants.END_OF_CHAIN) { thisBlock = blockStore.getFreeBlock(); loopDetector.claim(thisBlock); - + // We're on the end of the chain nextBlock = POIFSConstants.END_OF_CHAIN; - + // Mark the previous block as carrying on to us if needed if(prevBlock != POIFSConstants.END_OF_CHAIN) { blockStore.setNextBlock(prevBlock, thisBlock); } blockStore.setNextBlock(thisBlock, POIFSConstants.END_OF_CHAIN); - - // If we've just written the first block on a + + // If we've just written the first block on a // new stream, save the start block offset if(startBlock == POIFSConstants.END_OF_CHAIN) { startBlock = thisBlock; @@ -221,7 +222,7 @@ public class POIFSStream implements Iterable<ByteBuffer> } buffer = blockStore.createBlockIfNeeded(thisBlock); - + // Update pointers prevBlock = thisBlock; } @@ -249,12 +250,12 @@ public class POIFSStream implements Iterable<ByteBuffer> len -= writeBytes; } while (len > 0); } - + public void close() throws IOException { // If we're overwriting, free any remaining blocks POIFSStream toFree = new POIFSStream(blockStore, nextBlock); toFree.free(loopDetector); - + // Mark the end of the stream, if we have any data if (prevBlock != POIFSConstants.END_OF_CHAIN) { blockStore.setNextBlock(prevBlock, POIFSConstants.END_OF_CHAIN); diff --git a/src/java/org/apache/poi/util/StringCodepointsIterable.java b/src/java/org/apache/poi/util/StringCodepointsIterable.java index a56a6ae6c1..5fb83935bb 100644 --- a/src/java/org/apache/poi/util/StringCodepointsIterable.java +++ b/src/java/org/apache/poi/util/StringCodepointsIterable.java @@ -18,6 +18,7 @@ package org.apache.poi.util; import java.util.Iterator; +import java.util.NoSuchElementException; // based on https://gist.github.com/EmmanuelOga/48df70b27ead4d80234b @Internal @@ -37,6 +38,9 @@ public class StringCodepointsIterable implements Iterable<String> { @Override public String next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } int codePoint = StringCodepointsIterable.this.string.codePointAt(index); index += Character.charCount(codePoint); return new String(Character.toChars(codePoint)); diff --git a/src/java/org/apache/poi/util/StringUtil.java b/src/java/org/apache/poi/util/StringUtil.java index b946d65430..2bf29a55a0 100644 --- a/src/java/org/apache/poi/util/StringUtil.java +++ b/src/java/org/apache/poi/util/StringUtil.java @@ -17,9 +17,10 @@ package org.apache.poi.util; +import static java.nio.charset.StandardCharsets.ISO_8859_1; + import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.util.Iterator; import java.util.Locale; /** @@ -27,7 +28,6 @@ import java.util.Locale; */ @Internal public final class StringUtil { - private static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1; //arbitrarily selected; may need to increase private static final int MAX_RECORD_LENGTH = 10000000; @@ -305,38 +305,6 @@ public final class StringUtil { return haystack.regionMatches(true, start, suffix, 0, length); } - /** - * An Iterator over an array of Strings. - */ - public static class StringsIterator implements Iterator<String> { - private String[] strings = {}; - private int position; - - public StringsIterator(String[] strings) { - if (strings != null) { - this.strings = strings.clone(); - } - } - - @Override - public boolean hasNext() { - return position < strings.length; - } - - @Override - public String next() { - int ourPos = position++; - if (ourPos >= strings.length) { - throw new ArrayIndexOutOfBoundsException(ourPos); - } - return strings[ourPos]; - } - - @Override - public void remove() { - } - } - @Internal public static String toLowerCase(char c) { return Character.toString(c).toLowerCase(Locale.ROOT); diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java index 2e603fe261..228cfd285f 100644 --- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java +++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfComment.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.function.Supplier; import org.apache.poi.common.usermodel.GenericRecord; @@ -172,6 +173,9 @@ public class HemfComment { @Override public EmfCommentData next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } EmfCommentData toReturn = currentRecord; final boolean isEOF = (limit == -1 || leis.getReadIndex() >= startIdx+limit); // (currentRecord instanceof HemfPlusMisc.EmfEof) diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordIterator.java b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordIterator.java index dc5a2e3d57..bbe930f4ac 100644 --- a/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordIterator.java +++ b/src/scratchpad/src/org/apache/poi/hemf/record/emf/HemfRecordIterator.java @@ -19,6 +19,7 @@ package org.apache.poi.hemf.record.emf; import java.io.IOException; import java.util.Iterator; +import java.util.NoSuchElementException; import org.apache.poi.util.LittleEndianConsts; import org.apache.poi.util.LittleEndianInputStream; @@ -44,6 +45,9 @@ public class HemfRecordIterator implements Iterator<HemfRecord> { @Override public HemfRecord next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } HemfRecord toReturn = currentRecord; currentRecord = (currentRecord instanceof HemfMisc.EmfEof) ? null : _next(); return toReturn; diff --git a/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java b/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java index d30ba5d79c..032ef0a86c 100644 --- a/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java +++ b/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusRecordIterator.java @@ -19,6 +19,7 @@ package org.apache.poi.hemf.record.emfplus; import java.io.IOException; import java.util.Iterator; +import java.util.NoSuchElementException; import org.apache.poi.util.LittleEndianInputStream; import org.apache.poi.util.RecordFormatException; @@ -49,6 +50,9 @@ public class HemfPlusRecordIterator implements Iterator<HemfPlusRecord> { @Override public HemfPlusRecord next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } HemfPlusRecord toReturn = currentRecord; // add the size for recordId/flags/recordSize/dataSize = 12 bytes final boolean isEOF = (limit == -1 || (leis.getReadIndex()-startIdx)+12 > limit); diff --git a/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java b/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java index 0dff34f567..e11f005fe3 100644 --- a/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java +++ b/src/scratchpad/src/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java @@ -16,6 +16,17 @@ ==================================================================== */ package org.apache.poi.hsmf.extractor; +import static org.apache.poi.util.StringUtil.startsWithIgnoreCase; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.Locale; + import org.apache.poi.extractor.POIOLE2TextExtractor; import org.apache.poi.hsmf.MAPIMessage; import org.apache.poi.hsmf.datatypes.AttachmentChunks; @@ -24,16 +35,6 @@ import org.apache.poi.hsmf.exceptions.ChunkNotFoundException; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.util.LocaleUtil; -import org.apache.poi.util.Removal; -import org.apache.poi.util.StringUtil.StringsIterator; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.text.SimpleDateFormat; -import java.util.Locale; - -import static org.apache.poi.util.StringUtil.startsWithIgnoreCase; /** * A text extractor for HSMF (Outlook) .msg files. @@ -90,13 +91,11 @@ public class OutlookTextExtractor extends POIOLE2TextExtractor { msg.guess7BitEncoding(); // Off we go - StringsIterator emails; + Iterator<String> emails; try { - emails = new StringsIterator( - msg.getRecipientEmailAddressList() - ); + emails = Arrays.asList(msg.getRecipientEmailAddressList()).iterator(); } catch (ChunkNotFoundException e) { - emails = new StringsIterator(new String[0]); + emails = Collections.emptyIterator(); } try { @@ -174,7 +173,7 @@ public class OutlookTextExtractor extends POIOLE2TextExtractor { * of emails, and does its best to return something like * "Nick <nick@example.com>; Jim <jim@example.com>" */ - protected void handleEmails(StringBuilder s, String type, String displayText, StringsIterator emails) { + protected void handleEmails(StringBuilder s, String type, String displayText, Iterator<String> emails) { if (displayText == null || displayText.length() == 0) { return; } diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java b/src/testcases/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java index b1fa580f75..65d9265ab0 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestFilteringDirectoryNode.java @@ -18,18 +18,23 @@ package org.apache.poi.poifs.filesystem; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; - /** * Class to test FilteringDirectoryNode functionality */ @@ -68,16 +73,20 @@ public final class TestFilteringDirectoryNode { assertFalse(d.getEntry(eRoot.getName()).isDirectoryEntry()); assertTrue(d.getEntry(eRoot.getName()).isDocumentEntry()); - Iterator<Entry> i = d.getEntries(); - assertEquals(dirA, i.next()); - assertEquals(dirB, i.next()); - assertEquals(eRoot, i.next()); - assertNull(i.next()); + Iterator<Entry> i = d.getEntries(); + assertEquals(dirA, i.next()); + assertEquals(dirB, i.next()); + assertEquals(eRoot, i.next()); + try { + assertNull(i.next()); + fail("Should throw NoSuchElementException when depleted"); + } catch (NoSuchElementException ignored) { + } } @Test public void testChildFiltering() throws Exception { - List<String> excl = Arrays.asList(new String[]{"NotThere", "AlsoNotThere", eRoot.getName()}); + List<String> excl = Arrays.asList("NotThere", "AlsoNotThere", eRoot.getName()); FilteringDirectoryNode d = new FilteringDirectoryNode(fs.getRoot(), excl); assertEquals(2, d.getEntryCount()); @@ -96,11 +105,15 @@ public final class TestFilteringDirectoryNode { Iterator<Entry> i = d.getEntries(); assertEquals(dirA, i.next()); assertEquals(dirB, i.next()); - assertNull(i.next()); + try { + assertNull(i.next()); + fail("Should throw NoSuchElementException when depleted"); + } catch (NoSuchElementException ignored) { + } // Filter more - excl = Arrays.asList(new String[]{"NotThere", "AlsoNotThere", eRoot.getName(), dirA.getName()}); + excl = Arrays.asList("NotThere", "AlsoNotThere", eRoot.getName(), dirA.getName()); d = new FilteringDirectoryNode(fs.getRoot(), excl); assertEquals(1, d.getEntryCount()); @@ -122,11 +135,15 @@ public final class TestFilteringDirectoryNode { i = d.getEntries(); assertEquals(dirB, i.next()); - assertNull(i.next()); + try { + assertNull(i.next()); + fail("Should throw NoSuchElementException when depleted"); + } catch (NoSuchElementException ignored) { + } // Filter everything - excl = Arrays.asList(new String[]{"NotThere", eRoot.getName(), dirA.getName(), dirB.getName()}); + excl = Arrays.asList("NotThere", eRoot.getName(), dirA.getName(), dirB.getName()); d = new FilteringDirectoryNode(fs.getRoot(), excl); assertEquals(0, d.getEntryCount()); @@ -151,17 +168,19 @@ public final class TestFilteringDirectoryNode { } i = d.getEntries(); - assertNull(i.next()); + try { + assertNull(i.next()); + fail("Should throw NoSuchElementException when depleted"); + } catch (NoSuchElementException ignored) { + } } @Test public void testNestedFiltering() throws Exception { - List<String> excl = Arrays.asList(new String[]{ - dirA.getName() + "/" + "MadeUp", - dirA.getName() + "/" + eA.getName(), - dirA.getName() + "/" + dirAA.getName() + "/Test", - eRoot.getName() - }); + List<String> excl = Arrays.asList(dirA.getName() + "/" + "MadeUp", + dirA.getName() + "/" + eA.getName(), + dirA.getName() + "/" + dirAA.getName() + "/Test", + eRoot.getName()); FilteringDirectoryNode d = new FilteringDirectoryNode(fs.getRoot(), excl); // Check main diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSMiniStore.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSMiniStore.java index ea70b4f146..92ea46c698 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSMiniStore.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSMiniStore.java @@ -26,6 +26,7 @@ import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; import java.util.Iterator; +import java.util.NoSuchElementException; import org.apache.poi.POIDataSamples; import org.apache.poi.poifs.common.POIFSConstants; @@ -38,7 +39,7 @@ import org.junit.Test; @SuppressWarnings("CatchMayIgnoreException") public final class TestPOIFSMiniStore { private static final POIDataSamples _inst = POIDataSamples.getPOIFSInstance(); - + /** * Check that for a given mini block, we can correctly figure * out what the next one is @@ -52,24 +53,24 @@ public final class TestPOIFSMiniStore { POIFSFileSystem fsD = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi")); for(POIFSFileSystem fs : new POIFSFileSystem[] {fsA,fsB,fsC,fsD}) { POIFSMiniStore ministore = fs.getMiniStore(); - + // 0 -> 51 is one stream for(int i=0; i<50; i++) { assertEquals(i+1, ministore.getNextBlock(i)); } assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(50)); - + // 51 -> 103 is the next for(int i=51; i<103; i++) { assertEquals(i+1, ministore.getNextBlock(i)); } assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(103)); - + // Then there are 3 one block ones assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(104)); assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(105)); assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(106)); - + // 107 -> 154 is the next for(int i=107; i<154; i++) { assertEquals(i+1, ministore.getNextBlock(i)); @@ -81,32 +82,32 @@ public final class TestPOIFSMiniStore { assertEquals(i+1, ministore.getNextBlock(i)); } assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(160)); - + // 161 -> 166 is the next for(int i=161; i<166; i++) { assertEquals(i+1, ministore.getNextBlock(i)); } assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(166)); - + // 167 -> 172 is the next for(int i=167; i<172; i++) { assertEquals(i+1, ministore.getNextBlock(i)); } assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(172)); - + // Now some short ones assertEquals(174 , ministore.getNextBlock(173)); assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(174)); - + assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(175)); - + assertEquals(177 , ministore.getNextBlock(176)); assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(177)); - + assertEquals(179 , ministore.getNextBlock(178)); assertEquals(180 , ministore.getNextBlock(179)); assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(180)); - + // 181 onwards is free for(int i=181; i<fs.getBigBlockSizeDetails().getBATEntriesPerBlock(); i++) { assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(i)); @@ -131,11 +132,11 @@ public final class TestPOIFSMiniStore { for(POIFSFileSystem fs : new POIFSFileSystem[] {fsA,fsB,fsC,fsD}) { // Mini stream should be at big block zero assertEquals(0, fs._get_property_table().getRoot().getStartBlock()); - + // Grab the ministore POIFSMiniStore ministore = fs.getMiniStore(); ByteBuffer b; - + // Runs from the start of the data section in 64 byte chungs b = ministore.getBlockAt(0); assertEquals((byte)0x9e, b.get()); @@ -146,7 +147,7 @@ public final class TestPOIFSMiniStore { assertEquals((byte)0x21, b.get()); assertEquals((byte)0xd2, b.get()); assertEquals((byte)0x11, b.get()); - + // And the next block b = ministore.getBlockAt(1); assertEquals((byte)0x00, b.get()); @@ -157,7 +158,7 @@ public final class TestPOIFSMiniStore { assertEquals((byte)0x02, b.get()); assertEquals((byte)0x00, b.get()); assertEquals((byte)0x00, b.get()); - + // Check the last data block b = ministore.getBlockAt(180); assertEquals((byte)0x30, b.get()); @@ -168,7 +169,7 @@ public final class TestPOIFSMiniStore { assertEquals((byte)0x00, b.get()); assertEquals((byte)0x00, b.get()); assertEquals((byte)0x80, b.get()); - + // And the rest until the end of the big block is zeros for(int i=181; i<184; i++) { b = ministore.getBlockAt(i); @@ -187,7 +188,7 @@ public final class TestPOIFSMiniStore { fsB.close(); fsA.close(); } - + /** * Ask for free blocks where there are some already * to be had from the SFAT @@ -196,27 +197,27 @@ public final class TestPOIFSMiniStore { public void testGetFreeBlockWithSpare() throws Exception { POIFSFileSystem fs = new POIFSFileSystem(_inst.getFile("BlockSize512.zvi")); POIFSMiniStore ministore = fs.getMiniStore(); - + // Our 2nd SBAT block has spares assertFalse(ministore.getBATBlockAndIndex(0).getBlock().hasFreeSectors()); assertTrue(ministore.getBATBlockAndIndex(128).getBlock().hasFreeSectors()); - + // First free one at 181 assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(181)); assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(182)); assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(183)); assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(184)); - + // Ask, will get 181 assertEquals(181, ministore.getFreeBlock()); - + // Ask again, will still get 181 as not written to assertEquals(181, ministore.getFreeBlock()); - + // Allocate it, then ask again ministore.setNextBlock(181, POIFSConstants.END_OF_CHAIN); assertEquals(182, ministore.getFreeBlock()); - + fs.close(); } @@ -228,21 +229,21 @@ public final class TestPOIFSMiniStore { public void testGetFreeBlockWithNoneSpare() throws Exception { POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); POIFSMiniStore ministore = fs.getMiniStore(); - + // We've spare ones from 181 to 255 for(int i=181; i<256; i++) { assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(i)); } - + // Check our SBAT free stuff is correct assertFalse(ministore.getBATBlockAndIndex(0).getBlock().hasFreeSectors()); assertTrue(ministore.getBATBlockAndIndex(128).getBlock().hasFreeSectors()); - + // Allocate all the spare ones for(int i=181; i<256; i++) { ministore.setNextBlock(i, POIFSConstants.END_OF_CHAIN); } - + // SBAT are now full, but there's only the two assertFalse(ministore.getBATBlockAndIndex(0).getBlock().hasFreeSectors()); assertFalse(ministore.getBATBlockAndIndex(128).getBlock().hasFreeSectors()); @@ -250,30 +251,30 @@ public final class TestPOIFSMiniStore { assertFalse(ministore.getBATBlockAndIndex(256).getBlock().hasFreeSectors()); fail("Should only be two SBATs"); } catch(IndexOutOfBoundsException e) {} - + // Now ask for a free one, will need to extend the SBAT chain assertEquals(256, ministore.getFreeBlock()); assertFalse(ministore.getBATBlockAndIndex(0).getBlock().hasFreeSectors()); assertFalse(ministore.getBATBlockAndIndex(128).getBlock().hasFreeSectors()); assertTrue(ministore.getBATBlockAndIndex(256).getBlock().hasFreeSectors()); - assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(254)); // 2nd SBAT + assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(254)); // 2nd SBAT assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(255)); // 2nd SBAT assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(256)); // 3rd SBAT assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(257)); // 3rd SBAT - + fs.close(); } - + /** - * Test that we will extend the underlying chain of + * Test that we will extend the underlying chain of * big blocks that make up the ministream as needed */ @Test public void testCreateBlockIfNeeded() throws Exception { POIFSFileSystem fs = new POIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi")); POIFSMiniStore ministore = fs.getMiniStore(); - + // 178 -> 179 -> 180, 181+ is free assertEquals(179 , ministore.getNextBlock(178)); assertEquals(180 , ministore.getNextBlock(179)); @@ -281,7 +282,7 @@ public final class TestPOIFSMiniStore { for(int i=181; i<256; i++) { assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(i)); } - + // However, the ministore data only covers blocks to 183 for(int i=0; i<=183; i++) { ministore.getBlockAt(i); @@ -289,8 +290,8 @@ public final class TestPOIFSMiniStore { try { ministore.getBlockAt(184); fail("No block at 184"); - } catch(IndexOutOfBoundsException e) {} - + } catch(NoSuchElementException e) {} + // The ministore itself is made up of 23 big blocks Iterator<ByteBuffer> it = new POIFSStream(fs, fs.getRoot().getProperty().getStartBlock()).getBlockIterator(); int count = 0; @@ -299,10 +300,10 @@ public final class TestPOIFSMiniStore { it.next(); } assertEquals(23, count); - + // Ask it to get block 184 with creating, it will do ministore.createBlockIfNeeded(184); - + // The ministore should be one big block bigger now it = new POIFSStream(fs, fs.getRoot().getProperty().getStartBlock()).getBlockIterator(); count = 0; @@ -311,7 +312,7 @@ public final class TestPOIFSMiniStore { it.next(); } assertEquals(24, count); - + // The mini block block counts now run to 191 for(int i=0; i<=191; i++) { ministore.getBlockAt(i); @@ -319,14 +320,14 @@ public final class TestPOIFSMiniStore { try { ministore.getBlockAt(192); fail("No block at 192"); - } catch(IndexOutOfBoundsException e) {} - - + } catch(NoSuchElementException e) {} + + // Now try writing through to 192, check that the SBAT and blocks are there byte[] data = new byte[15*64]; POIFSStream stream = new POIFSStream(ministore, 178); stream.updateContents(data); - + // Check now assertEquals(179 , ministore.getNextBlock(178)); assertEquals(180 , ministore.getNextBlock(179)); @@ -346,10 +347,10 @@ public final class TestPOIFSMiniStore { for(int i=193; i<256; i++) { assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(i)); } - + fs.close(); } - + @Test public void testCreateMiniStoreFirst() throws Exception { POIFSFileSystem fs = new POIFSFileSystem(); @@ -365,14 +366,14 @@ public final class TestPOIFSMiniStore { try { ministore.getNextBlock(0); } catch (IndexOutOfBoundsException e) {} - + // Write a very small new document, will populate the ministore for us byte[] data = new byte[8]; for (int i=0; i<data.length; i++) { data[i] = (byte)(i+42); } fs.getRoot().createDocument("mini", new ByteArrayInputStream(data)); - + // Should now have a mini-fat and a mini-stream assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0)); assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,fs.getNextBlock(1)); @@ -381,11 +382,11 @@ public final class TestPOIFSMiniStore { assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(4)); assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(0)); assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(1)); - + // Re-fetch the mini store, and add it a second time ministore = fs.getMiniStore(); fs.getRoot().createDocument("mini2", new ByteArrayInputStream(data)); - + // Main unchanged, ministore has a second assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0)); assertEquals(POIFSConstants.FAT_SECTOR_BLOCK,fs.getNextBlock(1)); @@ -395,7 +396,7 @@ public final class TestPOIFSMiniStore { assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(0)); assertEquals(POIFSConstants.END_OF_CHAIN, ministore.getNextBlock(1)); assertEquals(POIFSConstants.UNUSED_BLOCK, ministore.getNextBlock(2)); - + // Check the data is unchanged and the right length entry = (DocumentEntry)fs.getRoot().getEntry("mini"); assertEquals(data.length, entry.getSize()); @@ -404,7 +405,7 @@ public final class TestPOIFSMiniStore { IOUtils.readFully(dis, rdata); assertArrayEquals(data, rdata); dis.close(); - + entry = (DocumentEntry)fs.getRoot().getEntry("mini2"); assertEquals(data.length, entry.getSize()); rdata = new byte[data.length]; @@ -416,7 +417,7 @@ public final class TestPOIFSMiniStore { // Done fs.close(); } - + @Test public void testMultiBlockStream() throws Exception { byte[] data1B = new byte[63]; @@ -427,7 +428,7 @@ public final class TestPOIFSMiniStore { for (int i=0; i<data2B.length; i++) { data2B[i] = (byte)(i+4); } - + // New filesystem and store to use POIFSFileSystem fs = new POIFSFileSystem(); @@ -435,41 +436,41 @@ public final class TestPOIFSMiniStore { assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0)); assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1)); assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(2)); - + // Store the 2 block one, should use 2 mini blocks, and request // the use of 2 big blocks POIFSMiniStore ministore = fs.getMiniStore(); fs.getRoot().createDocument("mini2", new ByteArrayInputStream(data2B)); - + // Check assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0)); assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1)); assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2)); // SBAT assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3)); // Mini assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(4)); - + // First 2 Mini blocks will be used assertEquals(2, ministore.getFreeBlock()); - + // Add one more mini-stream, and check fs.getRoot().createDocument("mini1", new ByteArrayInputStream(data1B)); - + assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(0)); assertEquals(POIFSConstants.FAT_SECTOR_BLOCK, fs.getNextBlock(1)); assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(2)); // SBAT assertEquals(POIFSConstants.END_OF_CHAIN, fs.getNextBlock(3)); // Mini assertEquals(POIFSConstants.UNUSED_BLOCK, fs.getNextBlock(4)); - + // One more mini-block will be used assertEquals(3, ministore.getFreeBlock()); - + // Check the contents too byte[] r1 = new byte[data1B.length]; DocumentInputStream dis = fs.createDocumentInputStream("mini1"); IOUtils.readFully(dis, r1); dis.close(); assertArrayEquals(data1B, r1); - + byte[] r2 = new byte[data2B.length]; dis = fs.createDocumentInputStream("mini2"); IOUtils.readFully(dis, r2); diff --git a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSStream.java b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSStream.java index 7819b4d1c4..c6a0a6a77b 100644 --- a/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSStream.java +++ b/src/testcases/org/apache/poi/poifs/filesystem/TestPOIFSStream.java @@ -36,6 +36,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.Iterator; +import java.util.NoSuchElementException; import org.apache.poi.POIDataSamples; import org.apache.poi.hpsf.DocumentSummaryInformation; @@ -72,12 +73,8 @@ public final class TestPOIFSStream { POIFSStream stream = new POIFSStream(fs, 98); Iterator<ByteBuffer> i = stream.getBlockIterator(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b = i.next(); assertFalse(i.hasNext()); - assertFalse(i.hasNext()); - assertFalse(i.hasNext()); // Check the contents assertEquals((byte)0x81, b.get()); @@ -103,15 +100,10 @@ public final class TestPOIFSStream { POIFSStream stream = new POIFSStream(fs, 97); Iterator<ByteBuffer> i = stream.getBlockIterator(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b97 = i.next(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b98 = i.next(); assertFalse(i.hasNext()); - assertFalse(i.hasNext()); - assertFalse(i.hasNext()); // Check the contents of the 1st block assertEquals((byte)0x01, b97.get()); @@ -169,18 +161,21 @@ public final class TestPOIFSStream { // Check the contents // 1st block is at 0 + assertNotNull(b0); assertEquals((byte)0x9e, b0.get()); assertEquals((byte)0x75, b0.get()); assertEquals((byte)0x97, b0.get()); assertEquals((byte)0xf6, b0.get()); // 2nd block is at 1 + assertNotNull(b1); assertEquals((byte)0x86, b1.get()); assertEquals((byte)0x09, b1.get()); assertEquals((byte)0x22, b1.get()); assertEquals((byte)0xfb, b1.get()); // last block is at 89 + assertNotNull(b22); assertEquals((byte)0xfe, b22.get()); assertEquals((byte)0xff, b22.get()); assertEquals((byte)0x00, b22.get()); @@ -204,18 +199,12 @@ public final class TestPOIFSStream { POIFSStream stream = new POIFSStream(fs, 0); Iterator<ByteBuffer> i = stream.getBlockIterator(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b0 = i.next(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b1 = i.next(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b2 = i.next(); assertFalse(i.hasNext()); - assertFalse(i.hasNext()); - assertFalse(i.hasNext()); // Check the contents of the 1st block assertEquals((byte)0x9E, b0.get()); @@ -304,17 +293,12 @@ public final class TestPOIFSStream { POIFSStream stream = new POIFSStream(ministore, 178); Iterator<ByteBuffer> i = stream.getBlockIterator(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b178 = i.next(); assertTrue(i.hasNext()); - assertTrue(i.hasNext()); ByteBuffer b179 = i.next(); assertTrue(i.hasNext()); ByteBuffer b180 = i.next(); assertFalse(i.hasNext()); - assertFalse(i.hasNext()); - assertFalse(i.hasNext()); // Check the contents of the 1st block assertEquals((byte)0xfe, b178.get()); @@ -803,7 +787,7 @@ public final class TestPOIFSStream { try { ministore.getBlockAt(184); fail("Block 184 should be off the end of the list"); - } catch (IndexOutOfBoundsException e) { + } catch (NoSuchElementException e) { } data = new byte[64 * 6 + 12]; diff --git a/src/testcases/org/apache/poi/util/TestStringUtil.java b/src/testcases/org/apache/poi/util/TestStringUtil.java index 184cf12cf4..b70a7dbda1 100644 --- a/src/testcases/org/apache/poi/util/TestStringUtil.java +++ b/src/testcases/org/apache/poi/util/TestStringUtil.java @@ -24,7 +24,6 @@ import static org.junit.Assert.fail; import java.nio.charset.Charset; -import org.apache.poi.util.StringUtil.StringsIterator; import org.junit.Test; /** @@ -128,52 +127,6 @@ public class TestStringUtil { } @Test - public void testStringsIterator() { - StringsIterator i; - - - i = new StringsIterator(new String[0]); - assertFalse(i.hasNext()); - try { - i.next(); - fail(); - } catch(ArrayIndexOutOfBoundsException e) { - // expected here - } - - - i = new StringsIterator(new String[] {"1"}); - assertTrue(i.hasNext()); - assertEquals("1", i.next()); - - assertFalse(i.hasNext()); - try { - i.next(); - fail(); - } catch(ArrayIndexOutOfBoundsException e) { - // expected here - } - - - i = new StringsIterator(new String[] {"1","2","3"}); - assertTrue(i.hasNext()); - assertEquals("1", i.next()); - assertTrue(i.hasNext()); - assertEquals("2", i.next()); - assertTrue(i.hasNext()); - assertEquals("3", i.next()); - - assertFalse(i.hasNext()); - try { - i.next(); - fail(); - } catch(ArrayIndexOutOfBoundsException e) { - // expected here - } - } - - - @Test public void startsWithIgnoreCase() { assertTrue("same string", StringUtil.startsWithIgnoreCase("Apache POI", "Apache POI")); assertTrue("longer string", StringUtil.startsWithIgnoreCase("Apache POI project", "Apache POI")); @@ -181,7 +134,7 @@ public class TestStringUtil { assertFalse("leading whitespace should not be ignored", StringUtil.startsWithIgnoreCase(" Apache POI project", "Apache POI")); assertFalse("shorter string", StringUtil.startsWithIgnoreCase("Apache", "Apache POI")); } - + @Test public void endsWithIgnoreCase() { assertTrue("same string", StringUtil.endsWithIgnoreCase("Apache POI", "Apache POI")); @@ -190,34 +143,34 @@ public class TestStringUtil { assertFalse("trailing whitespace should not be ignored", StringUtil.endsWithIgnoreCase("Apache POI project ", "Apache POI")); assertFalse("shorter string", StringUtil.endsWithIgnoreCase("Apache", "Apache POI")); } - + @Test public void join() { assertEquals("", StringUtil.join(",")); // degenerate case: nothing to join assertEquals("abc", StringUtil.join(",", "abc")); // degenerate case: one thing to join, no trailing comma assertEquals("abc|def|ghi", StringUtil.join("|", "abc", "def", "ghi")); assertEquals("5|8.5|true|string", StringUtil.join("|", 5, 8.5, true, "string")); //assumes Locale prints number decimal point as a period rather than a comma - + String[] arr = new String[] { "Apache", "POI", "project" }; assertEquals("no separator", "ApachePOIproject", StringUtil.join(arr)); assertEquals("separator", "Apache POI project", StringUtil.join(arr, " ")); } - + @Test public void count() { String test = "Apache POI project\n\u00a9 Copyright 2016"; // supports search in null or empty string assertEquals("null", 0, StringUtil.countMatches(null, 'A')); assertEquals("empty string", 0, StringUtil.countMatches("", 'A')); - + assertEquals("normal", 2, StringUtil.countMatches(test, 'e')); assertEquals("normal, should not find a in escaped copyright", 1, StringUtil.countMatches(test, 'a')); - + // search for non-printable characters assertEquals("null character", 0, StringUtil.countMatches(test, '\0')); assertEquals("CR", 0, StringUtil.countMatches(test, '\r')); assertEquals("LF", 1, StringUtil.countMatches(test, '\n')); - + // search for unicode characters assertEquals("Unicode", 1, StringUtil.countMatches(test, '\u00a9')); } |