/*::.
==================================================================================================================================
=================================================¦ Copyright © 2003 Allen Baker ¦=================================================
+------------------------------+
File: XStringsIterator.java
Originator: Allen Baker (2003.01.01)
LayoutRev: 5
================================================================================================================================== */
/*.
==========================================================================================
Package
------------------------------------------------------------------------------------------ */
package cosmicabyss.com.lib;
/*.
==========================================================================================
Imports
------------------------------------------------------------------------------------------ */
import java.io.*;
import java.util.*;
/*::
======================================================================================================================== *//**
Instances of this class are iterators over collections or Files of XStrings.<P>
If an XStringsIterator instance is set to be non-case-sensitive, its methods will return instances of a case-insensitive
subclass of XString, namely an NCString.<P>
The advantage of using a XStringsIterator instead of a TextReaderIterator or Iterator is that you don't have to
explicitly cast the objects returned by next() and peek() to XString.
<P>
<DL>
<DT>
<B>
Example usage:
</B>
<DD>
<BLOCKQUOTE>
<PRE id="unindent">
=========================================================================================
We're going to create XStringIterators over a TextFile, an ArrayList,
and a HashSet.
-----------------------------------------------------------------------------------------
TextFile file = new TextFile("tmp.tmp");
ArrayList array = new ArrayList(400);
HashSet set = new HashSet(400);
=========================================================================================
We'll use the same XStringIterator variable to store the
XStringIterator for each of them.
-----------------------------------------------------------------------------------------
XStringsIterator iter;
=========================================================================================
First, iterate over the lines in the TextFile. Use this iteration
to populate the ArrayList and the HashSet.
-----------------------------------------------------------------------------------------
iter = new XStringsIterator(file);
while (iter.hasNext())
{
XString str = iter.next();
System.out.println(str);
array.add(str);
set.add(str);
}
=========================================================================================
Now iterate over the ArrayList
-----------------------------------------------------------------------------------------
iter = new XStringsIterator(array);
while (iter.hasNext())
{
XString str = iter.next();
System.out.println(str);
}
=========================================================================================
Now iterate over the HashSet
-----------------------------------------------------------------------------------------
iter = new XStringsIterator(set);
while (iter.hasNext())
{
XString str = iter.next();
System.out.println(str);
}
</PRE>
</BLOCKQUOTE>
</DD>
</DT>
<DT>
<B>
View Source:
</B>
<DD>
<A href="XStringsIterator.java.html">
xStringsIterator.java
</A>
</DD>
</DT>
<DT>
<B>
Author:
</B>
<DD>
<A href="mailto:sourcecode.v01@cosmicabyss.com">
Allen Baker
</A>
</DD>
</DT>
</DL>
*//*
======================================================================================================================== */
public class XStringsIterator
{
/*: :METHOD:000:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given the File to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#000">View source</A>
@param
pFile is the file to read from.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator(File pFile) throws Exception
{
iIter = new TextReaderIterator(pFile);
iFile = pFile;
}
/*: :METHOD:001:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given an InputStream (such as System.in) to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#001">View source</A>
@param
pInputStream is the InputStream to read from.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator(InputStream pInputStream) throws Exception
{
iIter = new TextReaderIterator(pInputStream);
iInputStream = pInputStream;
}
/*: :METHOD:002:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given a Collection to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#002">View source</A>
@param
pCollection is the Collection to read from.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator(Collection pCollection)
{
iIter = pCollection.iterator();
iCollection = pCollection;
}
/*: :METHOD:003:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given the name of the file to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#003">View source</A>
@param
pFileName is the name of the file to read from.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type> XStringsIterator(Type pFileName) throws Exception
{
iIter = new TextReaderIterator(pFileName);
iFileName = new XString(pFileName);
}
/*: :METHOD:004:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given the File to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#004">View source</A>
@param
pFile is the file to read from.
@param
pCaseSensitive sets the case-sensitivity of the instance created by this constructor. If
pCaseSensitive is set to true, then normal XStrings are returned from this instance's next() and
peek() methods. If set to false, then instances of a subclass of XString, namely NCStrings (No
Case Strings: objects that are not case sensitive) are returned from this instance's next() and
peek() methods.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator(File pFile, boolean pCaseSensitive) throws Exception
{
iIter = new TextReaderIterator(pFile);
iCaseSensitive = pCaseSensitive;
}
/*: :METHOD:005:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given an InputStream (such as System.in) to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#005">View source</A>
@param
pInputStream is the InputStream to read from.
@param
pCaseSensitive sets the case-sensitivity of the instance created by this constructor. If
pCaseSensitive is set to true, then normal XStrings are returned from this instance's next() and
peek() methods. If set to false, then instances of a subclass of XString, namely NCStrings (No
Case Strings: objects that are not case sensitive) are returned from this instance's next() and
peek() methods.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator(InputStream pInputStream, boolean pCaseSensitive) throws Exception
{
iIter = new TextReaderIterator(pInputStream);
iCaseSensitive = pCaseSensitive;
}
/*: :METHOD:006:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given a Collection to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#006">View source</A>
@param
pCollection is the Collection to read from.
@param
pCaseSensitive sets the case-sensitivity of the instance created by this constructor. If
pCaseSensitive is set to true, then normal XStrings are returned from this instance's next() and
peek() methods. If set to false, then instances of a subclass of XString, namely NCStrings (No
Case Strings: objects that are not case sensitive) are returned from this instance's next() and
peek() methods.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator(Collection pCollection, boolean pCaseSensitive)
{
iIter = pCollection.iterator();
iCaseSensitive = pCaseSensitive;
}
/*: :METHOD:007:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates a new XStringsIterator, given the name of the file to read from.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#007">View source</A>
@param
pFileName is the name of the file to read from.
@param
pCaseSensitive sets the case-sensitivity of the instance created by this constructor. If
pCaseSensitive is set to true, then normal XStrings are returned from this instance's next() and
peek() methods. If set to false, then instances of a subclass of XString, namely NCStrings (No
Case Strings: objects that are not case sensitive) are returned from this instance's next() and
peek() methods.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type> XStringsIterator(Type pFileName, boolean pCaseSensitive) throws Exception
{
iIter = new TextReaderIterator(pFileName);
iCaseSensitive = pCaseSensitive;
}
/*: :METHOD:008:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns true if the iteration has more elements. (In other words, returns true if next
would return an element rather than throwing an exception.)
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#008">View source</A>
@return
True if the iterator has more elements.
*//*
---------------------------------------------------------------------------------------------------- */
public boolean hasNext()
{
return ((iPushBackQueue.size() > 0) || iIter.hasNext());
}
/*: :METHOD:009:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns the next element in the iteration but does not move the iterator ahead. This
means that the next time peek() or next() is called, the same Sting is returned again.<P>
If this XStringsIterator is set to be non-case-sensitive, this method will return an instance of a
case-insensitive subclass of XString, namely an NCString.<P>
If there's no next element, this method throws a NoSuchElementException. To avoid this exception,
the user should always call hasNext() to test whether or not the iteration has a next element before
calling this method.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#009">View source</A>
@return
The next element in the iteration.
*//*
---------------------------------------------------------------------------------------------------- */
public XString peek() throws NoSuchElementException, UnsupportedOperationException
{
XString xstr = null;
// /*.
// ==========================================================================================
// for now, we don't support peeking at anything but a file.
// ------------------------------------------------------------------------------------------ */
// if ( ! Util.className(iIter).equals("cosmicabyss.com.utl.TextReaderIterator"))
// {
// throw new UnsupportedOperationException();
// }
/*.
==========================================================================================
If there's something on the pushback queue, it's the next thing in the iteration so peek
at it.
------------------------------------------------------------------------------------------ */
if (iPushBackQueue.size() > 0)
{
xstr = iPushBackQueue.peek();
}
/*.
==========================================================================================
Otherwise, do a real peek
------------------------------------------------------------------------------------------ */
else
{
xstr = (XString)((TextReaderIterator)iIter).peek();
}
/*.
==========================================================================================
If we're not being case sensitive, return an NCString
------------------------------------------------------------------------------------------ */
if ( ! iCaseSensitive)
{
xstr = new NCString(xstr);
}
return xstr;
}
/*: :METHOD:010:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method closes the underlying file if it is still open. It is generally not needed. It is
automatically called when the end of file is encountered. It is also automatically called during
garbage collection when the TextReaderIterator's finalize() method is called.<P>
It should be called by the user if the user abandons reading the file before the end of file has
been reached (before the hasNext() method returns false).<P>
It is harmless to call this method when the file is not open.<P>
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#010">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void cleanup()
{
/*.
==========================================================================================
Assume we're iterating over a file and call its cleanup()
------------------------------------------------------------------------------------------ */
try
{
((TextReaderIterator)iIter).cleanup();
}
/*.
==========================================================================================
If the assumption was wrong and were iterating over something else, an exception will be
thrown and we end up here. Nothing needs to be done to close an iterator over anything
else.
------------------------------------------------------------------------------------------ */
catch (Exception e)
{
}
}
/*: :METHOD:011:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns the next element in the interation.<P>
If this XStringsIterator is set to be non-case-sensitive, this method will return an instance of a
case-insensitive subclass of XString, namely an NCString.<P>
If there's no next element, this method throws a NoSuchElementException. To avoid this exception,
the user should always call hasNext() to test whether or not the iteration has a next element before
calling this method.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#011">View source</A>
@return
The next element in the iteration.
*//*
---------------------------------------------------------------------------------------------------- */
public XString next() throws Exception
{
XString xstr = null;
/*.
==========================================================================================
If there's something on the pushback queue, it's the next thing in the iteration.
------------------------------------------------------------------------------------------ */
if (iPushBackQueue.size() > 0)
{
xstr = iPushBackQueue.next();
}
/*.
==========================================================================================
Otherwise, do a real next
------------------------------------------------------------------------------------------ */
else
{
xstr = new XString(iIter.next());
}
/*.
==========================================================================================
If we're not being case sensitive, return an NCString
------------------------------------------------------------------------------------------ */
if ( ! iCaseSensitive)
{
xstr = new NCString(xstr);
}
return xstr;
}
/*: :METHOD:012:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method puts an XString into the iteration as the next XString that will be returned by the
iterator if the iterator is reading from a TextFile. It's used to support a look ahead capability by
putting an XString that the iterator served up through next() back to be served up again on the next
call to next(). It is also a mechanism for inserting XStrings that would not otherwise be there into
the XString stream being emitted by the iterator.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#012">View source</A>
@param
pStr is the object whose XString representation will be placed into the iteration stream.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void inject(Type1 pStr)
{
// /*.
// ==========================================================================================
// for now, we don't support injecting unless we're iterating over a file
// ------------------------------------------------------------------------------------------ */
// if ( ! Util.className(iIter).equals("cosmicabyss.com.utl.TextReaderIterator"))
// {
// throw new UnsupportedOperationException();
// }
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
XString str = XString.toXString(pStr);
iPushBackQueue.add(str);
}
/*: :METHOD:013:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method is not implemented. It is an optional method in the Iterator interface that removes from
the underlying collection the last element returned by the iterator. If this method is called it
will throw an UnsupportedOperationException.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#013">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void remove() throws UnsupportedOperationException
{
iIter.remove();
}
/*: :METHOD:014:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method resets the iterator to the beginning of whatever it was iterating over.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#014">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void reset() throws Exception
{
/*.
==========================================================================================
clean up and free the current iterator.
------------------------------------------------------------------------------------------ */
this.cleanup();
this.iIter = null;
/*.
==========================================================================================
free and recreate the pushback queue
------------------------------------------------------------------------------------------ */
this.iPushBackQueue = new Queue<XString>();
/*.
==========================================================================================
recreate the iterator
------------------------------------------------------------------------------------------ */
if (this.iFile != null)
{
this.iIter = new TextReaderIterator(this.iFile);
}
else if (this.iInputStream != null)
{
this.iIter = new TextReaderIterator(this.iInputStream);
}
else if (this.iCollection != null)
{
this.iIter = this.iCollection.iterator();
}
else if (this.iFileName != null)
{
this.iIter = new TextReaderIterator(this.iFileName);
}
}
/*: :METHOD:015:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method sets the ConsoleStream for this object.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#015">View source</A>
@return
A reference to this object
@param
pConsole is a ConsoleStream through which this objects sends its output.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator setOut(ConsoleStream pConsole)
{
cOut = pConsole;
return this;
}
/*: :METHOD:016:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This boilerplate method is used for testing an instantiated object of this class and may include any
code the developer chooses.
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#016">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator test() throws Exception
{
cOut.titledPrintf
(
"\"HELLO WORLD!\"",
"%s %s %s",
"I'm an object of the", CLASS_NAME, "class, and I approved this message."
);
while (this.hasNext())
{
XString str = this.next();
cOut.println(str);
}
return this;
}
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Protected ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Private ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*.
==========================================================================================
Class Constants
CLASS_NAME:
The name of this class
DFLT_LINE_LEN:
The default line length for word wrapping
------------------------------------------------------------------------------------------ */
private static final XString CLASS_NAME = new XString(XStringsIterator.class.getName());
private static final int DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();
/*.
==========================================================================================
Class variables
cOut : console output.
------------------------------------------------------------------------------------------ */
private static ConsoleStream cOut = ConsoleStream.getSingleton();
/*.
==========================================================================================
Instance variables
------------------------------------------------------------------------------------------ */
private Queue<XString> iPushBackQueue = new Queue<XString>();
private boolean iCaseSensitive = true;
private Iterator iIter = null;
private XString iFileName = null;
private Collection iCollection = null;
private InputStream iInputStream = null;
private File iFile = null;
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Inner Classes ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Public Static Methods ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*: :METHOD:017:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method allows this class file to be unit tested as a standalone application. It's the method
that's called when the class is invoked from the command line by using the java application launcher
- "java". Main() is not a required method, but the practice of putting one in each class and
wrapping class test code within it allows easy unit testing of the class; and main does not need to
be removed when testing is complete.
<P>
<DL>
<DT>
<B>
Command line usage:
</B>
<DD>
Java cosmicabyss.com.lib.XStringsIterator
</DD>
</DT>
</DL>
<P><B>Implementation: </B><A HREF="XStringsIterator.java.html#017">View source</A>
@param
pArgs contains the command line arguments with which this class was invoked as an application.
*//*
---------------------------------------------------------------------------------------------------- */
public static void main(String[] pArgs) throws Exception
{
/*.
==========================================================================================
Greetings !
------------------------------------------------------------------------------------------ */
cOut.banner(CLASS_NAME);
/*.
==========================================================================================
Create an object and send its output to the ConsoleStream
------------------------------------------------------------------------------------------ */
XStringsIterator obj = new XStringsIterator("c:/temp/test.txt");
/*.
==========================================================================================
Test code
------------------------------------------------------------------------------------------ */
obj.test();
/*.
==========================================================================================
We're going to create XStringIterators over a TextFile, an ArrayList, and a HashSet.
------------------------------------------------------------------------------------------ */
TextFile file = new TextFile("c:/temp/test.txt");
ArrayList<XString> array = new ArrayList<XString>();
HashSet<XString> set = new HashSet<XString>();
/*.
==========================================================================================
We'll use the same XStringIterator variable to store the XStringIterator for each of them.
------------------------------------------------------------------------------------------ */
XStringsIterator iter;
/*.
==========================================================================================
First, iterate over the lines in the TextFile. Use this iteration to populate the
ArrayList and the HashSet.
------------------------------------------------------------------------------------------ */
iter = new XStringsIterator(file);
while (iter.hasNext())
{
XString str = iter.next();
System.out.println(str);
array.add(str);
set.add(str);
}
/*.
==========================================================================================
Now iterate over the ArrayList
------------------------------------------------------------------------------------------ */
iter = new XStringsIterator(array);
while (iter.hasNext())
{
XString str = iter.next();
System.out.println(str);
}
/*.
==========================================================================================
Now iterate over the HashSet
------------------------------------------------------------------------------------------ */
iter = new XStringsIterator(set);
while (iter.hasNext())
{
XString str = iter.next();
System.out.println(str);
}
}
} // class XStringsIterator