/*::.
==================================================================================================================================
=================================================¦ Copyright © 2002 Allen Baker ¦=================================================
+------------------------------+
File: TextFile.java
Originator: Allen Baker (2002.12.30)
LayoutRev: 5
================================================================================================================================== */
/*.
==========================================================================================
Package
------------------------------------------------------------------------------------------ */
package cosmicabyss.com.lib;
/*.
==========================================================================================
Imports
------------------------------------------------------------------------------------------ */
import java.io.*;
import java.util.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.invoke.*;
/*::
======================================================================================================================== *//**
Instances of this class represent Files containing lines of text. A lot of things can be done with a file once you know
that it is this TextFile and this class provides methods to do many of those things. Most of the methods provided here
operate on the individual lines of this TextFile, permitting such things as de/entabbing, string replacement, trimming
in various ways, sorting, tabularizing, etc.. And since TextFile is a subclass of XFile, all the things that can be done
with an XFile can also be done with a TextFile.
<P>
<DL>
<DT>
<B>
Example usage:
</B>
<DD>
<BLOCKQUOTE>
<PRE id="unindent">
If the file named test.tmp comprises these lines:
1 22 333 4444 55555
1 22 333 4444 55555
11111 2222 333 44 5
1 22 333
1
then this code:
'
=========================================================================================
create a TextFile to play with
----------------------------------------------------------------------------------------- '
TextFile tf = new TextFile("test.tmp");
'
=========================================================================================
detab and trim the file
----------------------------------------------------------------------------------------- '
tf.detabAndTrim();
'
=========================================================================================
replace all the "2" strings in the file with "XY" strings
----------------------------------------------------------------------------------------- '
tf.replace("2","XY");
'
=========================================================================================
tabularize the file
----------------------------------------------------------------------------------------- '
tf.tabularize();
'
=========================================================================================
display the file
----------------------------------------------------------------------------------------- '
Iterator iter = tf.iterator();
while (iter.hasNext())
{
System.out.println((XString)iter.next());
}
will change test.tmp to look like this:
1 XYXY 333 4444 55555
1 XYXY 333 4444 55555
11111 XYXYXYXY 333 44 5
1 XYXY 333
1
</PRE>
</BLOCKQUOTE>
</DD>
</DT>
<DT>
<B>
View Source:
</B>
<DD>
<A href="TextFile.java.html">
TextFile.java
</A>
</DD>
</DT>
<DT>
<B>
Author:
</B>
<DD>
<A href="mailto:sourcecode.v01@cosmicabyss.com">
Allen Baker
</A>
</DD>
</DT>
</DL>
*//*
======================================================================================================================== */
public class TextFile extends XFile
{
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Public ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*: :METHOD:000:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates an instance of the TextFile class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#000">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public TextFile(XFile xfile) throws Exception
{
super(xfile.getCanonicalPath());
}
/*: :METHOD:001:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates an instance of the TextFile class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#001">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public TextFile(TextFile tfile) throws Exception
{
super(tfile.getCanonicalPath());
}
/*: :METHOD:002:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates an instance of the TextFile class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#002">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public TextFile(URI uri)
{
super(uri);
}
/*: :METHOD:003:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates an instance of the TextFile class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#003">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public TextFile(File file) throws Exception
{
super(file.getCanonicalPath());
}
/*: :METHOD:004:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates an instance of the TextFile class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#004">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> TextFile(File parent, Type1 child)
{
super(parent,child);
}
/*: :METHOD:005:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates an instance of the TextFile class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#005">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> TextFile(Type1 pathname)
{
super(pathname);
}
/*: :METHOD:006:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method creates an instance of the TextFile class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#006">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> TextFile(Type1 parent, Type2 child)
{
super(parent,child);
}
/*: :METHOD:007:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method searches each line of this TextFile for the string specified by pStr. As soon as it
finds the first instance of the string, it stops searching and immediately returns true. If it
reaches the end of this TextFile without finding the string, it returns false.
<P><B>Implementation: </B><A HREF="TextFile.java.html#007">View source</A>
@return
This method returns true if this TextFile contains any instance of the search string; otherwise
it returns false.
@param
pStr is an object whose string representation is used as the "search string." This TextFile is
searched for any instance of the search string.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> boolean containsString(Type1 pStr) throws Exception
{
boolean result = false;
XString str = XString.toXString(pStr);
/*.
==========================================================================================
Get the pathname of the input file
------------------------------------------------------------------------------------------ */
String inPathname = this.getCanonicalPath();
/*.
==========================================================================================
Make sure the input file exists.
------------------------------------------------------------------------------------------ */
if ( ! this.exists())
{
cOut.titledSeverityPrintf(Const.HALT, CLASS_NAME, "I/O Error: <" + inPathname +"> does not exist.");
throw new Exception("Input file does not exist.");
}
/*.
==========================================================================================
Make sure we're not messing with a directory.
------------------------------------------------------------------------------------------ */
if ( ! this.isFile())
{
cOut.titledSeverityPrintf(Const.HALT, CLASS_NAME, "I/O Error: <" + inPathname +"> is a directory.");
throw new Exception("Input file cannot be a directory.");
}
/*.
==========================================================================================
Set up the input iterator and output writer
------------------------------------------------------------------------------------------ */
XStringsIterator iter = new XStringsIterator(inPathname);
while (iter.hasNext())
{
if (iter.next().contains(str))
{
iter.cleanup();
result = true;
break;
}
}
return result;
}
/*: :METHOD:008:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method compares the content of this TextFile with another TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#008">View source</A>
@return
This method returns true if the content of the two file is the same, otherwise it returns false.
@param
pOtherFile is the other TextFile to compare this TextFile to.
@param
pIgnoreWhitespace tells this method to ignore whitespace if it is set to true. If false, this
method does not ignore whitespace.
*//*
---------------------------------------------------------------------------------------------------- */
public boolean contentEquals(TextFile pOtherFile, boolean pIgnoreWhiteSpace) throws Exception
{
StringBuffer thisFileBuf = new StringBuffer(2 * UMath.ONE_MEG);
StringBuffer thatFileBuf = new StringBuffer(2 * UMath.ONE_MEG);
XStringsIterator thisIter = this.xstringsIterator();
XStringsIterator thatIter = pOtherFile.xstringsIterator();
/*.
==========================================================================================
copy all the content of each TextFile into its own StringBuffer.
------------------------------------------------------------------------------------------ */
while (thisIter.hasNext())
{
thisFileBuf.append(thisIter.next().concat("\n").toString());
}
while (thatIter.hasNext())
{
thatFileBuf.append(thatIter.next().concat("\n").toString());
}
thisIter.cleanup();
thatIter.cleanup();
/*.
==========================================================================================
make each StringBuffer file representation into an XString file representation
------------------------------------------------------------------------------------------ */
XString thisFile = new XString(thisFileBuf.toString());
XString thatFile = new XString(thatFileBuf.toString());
/*.
==========================================================================================
free up all the memory that those two StringBuffers were consuming.
------------------------------------------------------------------------------------------ */
thisFileBuf = null;
thatFileBuf = null;
/*.
==========================================================================================
If we're ignoring whitespace, remove all of it from both XString file representations.
------------------------------------------------------------------------------------------ */
if (pIgnoreWhiteSpace)
{
thisFile = thisFile.removeWhitespace();
thatFile = thatFile.removeWhitespace();
}
/*.
==========================================================================================
Compare the XString file representations for equality and return the result
------------------------------------------------------------------------------------------ */
return thisFile.equals(thatFile);
}
/*: :METHOD:009:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method compares the content of this TextFile, including whitespace, with another TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#009">View source</A>
@return
This method returns true if the content of the two file is the same, otherwise it returns false.
@param
pOtherFile is the other TextFile to compare this TextFile to.
*//*
---------------------------------------------------------------------------------------------------- */
public boolean contentEquals(TextFile pOtherFile) throws Exception
{
return contentEquals(pOtherFile, false);
}
/*: :METHOD:010:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method facilitates applying the "modify file in place" pattern to this TextFile. This pattern
creates the "appearance" that this TextFile is modified in place. When this method completes, this
TextFile's content has been modified. The pattern is characterized by the following procedure:
<BLOCKQUOTE>
=> Open this TextFile for reading.<BR>
=> Open a new file for writing.<BR>
=> Get an iterator for reading this TextFile.<BR>
=> Get a writer for writing to the file opened for writing.<BR>
=> Pass the iterator and writer into a method (a delegate) that reads this TextFile using the
Iterator, modifies its content, and writes the modified content to the new file using the
writer.<BR>
=> Clean up and close the iterator.<BR>
=> Flush and close the writer.<BR>
=> Replace this TextFile with the new file that was opened for writing.
</BLOCKQUOTE>
The key feature of this method is that it is passed the name of a modification method as an argument
through its pMethodName parameter, and an arbitrary set of additional arguments through it pArguments
parameter. It identifies the class of this TextFile (it may be a TextFile instance or an instance of
a subclass of TextFile) and uses that information along with the modification method's name and the
additional arguments to find out what the modification method's return type is. It passes all this
information along to a method that performs all the logistical work of opening files, creating
iterators and writers, cleaning up iterators, flushing and closing writers, and replacing the input
file with the output file. That method delegates to the modification method the task of actually
modifying the content of the input file and putting it into the output file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#010">View source</A>
@return
This method returns whatever the modification method returns, if anything.
@param
pMethodName is the name of a modification method.
@param
pArguments is a variable length list of arguments [0..n arguments] to be passed to the
modification method when it is called. Each actual modification method has its own expectations
regarding what that arguments in the list are and what their types are.
*//*
---------------------------------------------------------------------------------------------------- */
@SuppressWarnings("unchecked")
public <Type1> Type1 modify(String pMethodName, Object... pArguments) throws Exception
{
Class<?> thisClass = this.getClass();
Method thisMethod = thisClass.getMethod(pMethodName, XStringsIterator.class, TextWriter.class, Object[].class);
return (Type1)modify(thisMethod.getReturnType(), pMethodName, pArguments);
}
/*: :METHOD:011:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method applies the "modify file in place" pattern to this TextFile. This pattern creates the
"appearance" that this TextFile is modified in place. When this method completes, this TextFile's
content has been modified. This method performs the following procedure:
<BLOCKQUOTE>
=> Open this TextFile for reading.<BR>
=> Open a new file for writing.<BR>
=> Get an iterator for reading this TextFile.<BR>
=> Get a writer for writing to the file opened for writing.<BR>
=> Pass the iterator and writer into a method (a delegate) that reads this TextFile using the
Iterator, modifies its content, and writes the modified content to the new file using the
writer.<BR>
=> Clean up and close the iterator.<BR>
=> Flush and close the writer.<BR>
=> Replace this TextFile with the new file that was opened for writing.
</BLOCKQUOTE>
The key feature of this method is that it encapsulates and hides all the reflection-like code that
is necessary to use the modification method as a delegate that modifies the content of the input
file and puts it into the output file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#011">View source</A>
@return
This method returns whatever the modification method returns, if anything.
@param
pReturnType is the class or type returned by the modification method.
@param
pMethodName is the name of a modification method.
@param
pArguments is a variable length list of arguments [0..n arguments] to be passed to the
modification method when it is called. Each actual modification method has its own expectations
regarding what that arguments in the list are and what their types are.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1, Type2> Type1 modify(Class<Type1> pReturnType, Type2 pMethodName, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Figure out the method to call from the parameters
------------------------------------------------------------------------------------------ */
String methodName = UString.toString(pMethodName);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType signature = MethodType.methodType(pReturnType, XStringsIterator.class, TextWriter.class, pArguments.getClass());
MethodHandle modifer = lookup.findVirtual(this.getClass(), methodName, signature);
/*.
==========================================================================================
This will catch the return value from modifier and return it from this method.
------------------------------------------------------------------------------------------ */
Type1 result;
/*.
==========================================================================================
Get the pathname of the input file (the file this method will modify "in place").
------------------------------------------------------------------------------------------ */
String inPathname = this.getCanonicalPath();
/*.
==========================================================================================
Get file for input, create file for output
------------------------------------------------------------------------------------------ */
File inFile = new File(inPathname);
File outFile = new XFile(Util.getTempFileName());
/*.
==========================================================================================
Get the pathname of the output file.
------------------------------------------------------------------------------------------ */
String outPathname = outFile.getCanonicalPath();
/*.
==========================================================================================
Make sure the input file exists.
------------------------------------------------------------------------------------------ */
if ( ! inFile.exists())
{
outFile.delete();
inFile = null;
outFile = null;
cOut.titledSeverityPrintf(Const.HALT, CLASS_NAME, "I/O Error: <" + inPathname +"> does not exist.");
throw new Exception("Input file does not exist.");
}
/*.
==========================================================================================
Make sure we're not messing with a directory.
------------------------------------------------------------------------------------------ */
if ( ! inFile.isFile())
{
outFile.delete();
inFile = null;
outFile = null;
cOut.titledSeverityPrintf(Const.HALT, CLASS_NAME, "I/O Error: <" + inPathname +"> is a directory.");
throw new Exception("Input file cannot be a directory.");
}
/*.
==========================================================================================
We just needed the pathnames so free the Files for the garbage collector.
------------------------------------------------------------------------------------------ */
inFile = null;
outFile = null;
/*.
==========================================================================================
Set up the input iterator and output writer
------------------------------------------------------------------------------------------ */
XStringsIterator iter = new XStringsIterator(inPathname);
TextWriter output = new TextWriter(outPathname);
/*.
==========================================================================================
MethodHandle.invoke throws a Throwable instead of an Exception. But we don't want to throw
a Throwable out of this method because every method up the call chain would have to be
modified to throw Throwables if we did. So catch it if it happens and convert it into an
Exception and throw that instead.
------------------------------------------------------------------------------------------ */
try
{
/*.
==========================================================================================
Call the method that was passed in to modify the file.
------------------------------------------------------------------------------------------ */
result = (Type1)modifer.invoke(this, iter, output, pArguments);
}
catch (Throwable cause)
{
throw new Exception(cause);
}
/*.
==========================================================================================
Make sure the iterator is all tidied up in case it was abandoned before reaching the end
of file.
------------------------------------------------------------------------------------------ */
iter.cleanup();
iter = null;
/*.
==========================================================================================
Flush the output's buffers to the OS, and close the file.
------------------------------------------------------------------------------------------ */
output.flush();
output.close();
output = null;
/*.
==========================================================================================
Delete the original file and replace it with the new file.
------------------------------------------------------------------------------------------ */
XFile.replaceFile(inPathname, outPathname);
return result;
}
/*: :METHOD:012:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns an Iterator over the lines in this TextFile. This TextFile is treated as an
ordered list of Strings. Each String contains one line of this TextFile. This provides an
alternative paradigm for reading this TextFile from the one provided by the BufferedReader or
TextReader class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#012">View source</A>
@return
An iterator over the lines in this TextFile in proper sequence.
*//*
---------------------------------------------------------------------------------------------------- */
public TextReaderIterator iterator() throws Exception
{
return new TextReaderIterator(this.getCanonicalPath());
}
/*: :METHOD:013:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns an Iterator over the chars in this TextFile. This TextFile is treated as an
ordered list of chars. This provides an alternative paradigm for reading this TextFile from the one
provided by the BufferedReader or TextReader class.
<P><B>Implementation: </B><A HREF="TextFile.java.html#013">View source</A>
@return
An iterator over the chars in this TextFile in proper sequence.
*//*
---------------------------------------------------------------------------------------------------- */
public CharIterator charIterator() throws Exception
{
return new CharIterator(this.getCanonicalPath());
}
/*: :METHOD:014:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns an Iterator over the lines in this TextFile. This TextFile is treated as an
ordered list of XStrings. Each XString contains one line of this TextFile. This provides an
alternative paradigm for reading this TextFile from the one provided by the BufferedReader or
TextReader class.<P>
The advantage of using a XStringsIterator instead of a TextReaderIterator is that you don't have to
explicitly cast the objects returned by next() and peek() to XString.
<P><B>Implementation: </B><A HREF="TextFile.java.html#014">View source</A>
@return
An iterator over the lines in this TextFile in proper sequence.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator xstringsIterator() throws Exception
{
return new XStringsIterator(this.getCanonicalPath());
}
/*: :METHOD:015:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns an Iterator over the lines in this TextFile. This TextFile is treated as an
ordered list of XStrings. Each XString contains one line of this TextFile. This provides an
alternative paradigm for reading this TextFile from the one provided by the BufferedReader or
TextReader class.<P>
The advantage of using a XStringsIterator instead of a TextReaderIterator is that you don't have to
explicitly cast the objects returned by next() and peek() to XString.
<P><B>Implementation: </B><A HREF="TextFile.java.html#015">View source</A>
@return
An iterator over the lines in this TextFile in proper sequence.
@param
pCaseSensitive specifies whether or not the new XString is case sensitive.
*//*
---------------------------------------------------------------------------------------------------- */
public XStringsIterator xstringsIterator(boolean pCaseSensitive) throws Exception
{
return new XStringsIterator(this.getCanonicalPath(),pCaseSensitive);
}
/*: :METHOD:016:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns a convenience object for buffered reading of this TextFile. A TextReader reads
text from this TextFile as a character-input stream, buffering characters so as to provide efficient
reading.
<P><B>Implementation: </B><A HREF="TextFile.java.html#016">View source</A>
@return
A buffered reader for reading the lines in this TextFile in proper sequence.
*//*
---------------------------------------------------------------------------------------------------- */
public TextReader reader() throws Exception
{
return new TextReader(this.getCanonicalPath());
}
/*: :METHOD:017:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns a convenience object for buffered writing of this TextFile. A TextWriter writes
text to this TextFile as a character-output stream, buffering characters so as to provide efficient
writing.
<P><B>Implementation: </B><A HREF="TextFile.java.html#017">View source</A>
@return
A buffered writer for writing the lines to this TextFile in proper sequence.
*//*
---------------------------------------------------------------------------------------------------- */
public TextWriter writer() throws Exception
{
return new TextWriter(this.getCanonicalPath());
}
/*: :METHOD:018:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method returns a PrintWriter for writing to this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#018">View source</A>
@return
A PrintWriter for writing to this TextFile.
*//*
---------------------------------------------------------------------------------------------------- */
public PrintWriter printWriter() throws Exception
{
return new PrintWriter(this.writer());
}
/*: :METHOD:019:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method does a case-sensitive replacment of all instances of pOldString with pNewString
throughout this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#019">View source</A>
@param
pOldString is the substring that will be replaced.
@param
pNewString is the XString that will replace the pOldString.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void replace(Type1 pOldString, Type2 pNewString) throws Exception
{
this.replace(pOldString, pNewString, true);
}
/*: :METHOD:020:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all instances of pOldString with pNewString throughout this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#020">View source</A>
@param
pOldString is the substring that will be replaced.
@param
pNewString is the XString that will replace the pOldString.
@param
pCaseSensitive specifies whether or not to use case considerations. True means case sensitive,
false means case in-sensitive.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void replace(Type1 pOldString, Type2 pNewString, boolean pCaseSensitive) throws Exception
{
XString[][] strPairs =
{
{XString.toXString(pOldString), XString.toXString(pNewString)}
};
this.replace(strPairs, pCaseSensitive);
}
/*: :METHOD:021:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
For each pair of Strings in pStrPairs, this method does a case-sensitive replacment of all instances
of the first String in the pair with the second String in the pair throughout this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#021">View source</A>
@param
pStrPairs is an array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects whose String
representations will be used. The first of the two Strings is the String that will be replaced.
The second is the String that will replace the first.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void replace(Type1[][] pStrPairs) throws Exception
{
this.replace(pStrPairs, true);
}
/*: :METHOD:022:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
For each pair of Strings in pStrPairs, this method replaces all instances of the first String in the
pair with the second String in the pair throughout this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#022">View source</A>
@param
pStrPairs is an array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects whose String
representations will be used. The first of the two Strings is the String that will be replaced.
The second is the String that will replace the first.
@param
pCaseSensitive specifies whether or not to use case considerations. True means case sensitive,
false means case in-sensitive.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void replace(Type1[][] pStrPairs, boolean pCaseSensitive) throws Exception
{
this.modify("replace", pStrPairs, pCaseSensitive);
}
/*: :METHOD:023:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is String replacement. It receives an argument that is an
array of 2-element arrays. Each 2-element array contains 2 Strings. The first String is text to
search for in this TextFile and the second String is a replacement for each occurrence of the first
String that is found.
<P><B>Implementation: </B><A HREF="TextFile.java.html#023">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: Type1[][] strPairs
<BLOCKQUOTE>
An array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects
whose String representations will be used. The first of the two strings is the String
that will be replaced. The second is the String that will replace the first.
</BLOCKQUOTE>
pArguments[1]: boolean caseSensitive
<BLOCKQUOTE>
A boolean that specifies whether or not to use case considerations. True means case
sensitive, false means case in-sensitive.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
@SuppressWarnings("unchecked")
public <Type1> void replace(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
Type1[][] strPairs = (Type1[][])pArguments[0];
boolean caseSensitive = (boolean)pArguments[1];
/*.
==========================================================================================
Read each line of this TextFile replacing all the substrings and writing the modified
lines to the pOutput file. The EOL that is lost when reading from a TextReader is
reattached so that replacement searches will work with EOL.
------------------------------------------------------------------------------------------ */
StringBuilder theWholeFile = new StringBuilder(2 * UMath.ONE_MEG);
while (pIter.hasNext())
{
XString s = pIter.next();
s = s.trimRight();
s = s.concat("\n");
theWholeFile.append(s.toString());
}
XString wholeFile = new XString(theWholeFile.toString());
theWholeFile = null;
if (caseSensitive)
{
for (int i=0; i<strPairs.length; i++)
{
wholeFile = wholeFile.replace(strPairs[i][0],strPairs[i][1]);
}
}
else
{
for (int i=0; i<strPairs.length; i++)
{
wholeFile = wholeFile.replaceIgnoreCase(strPairs[i][0],strPairs[i][1]);
}
}
wholeFile = wholeFile.trimRight("\n");
pOutput.print(wholeFile);
}
/*: :METHOD:024:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all instances throughout this TextFile of substrings matching the regular
expression in pOldString with a string generated from the regular expression in pNewString.
<P><B>Implementation: </B><A HREF="TextFile.java.html#024">View source</A>
@param
pOldString is the regular expression to which this text in this TextFile is to be matched.
@param
pNewString is the the string to be substituted for each match.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void replaceRegex(Type1 pOldString, Type2 pNewString) throws Exception
{
XString[][] strPairs =
{
{XString.toXString(pOldString), XString.toXString(pNewString)}
};
this.replaceRegex(strPairs);
}
/*: :METHOD:025:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
For each pair of regular expression Strings in pStrPairs, this method replaces all instances
throughout this TextFile of substrings matching the regular expression of the first String in the
pair with the String generated from the regular expression in the second String in the pair.
<P><B>Implementation: </B><A HREF="TextFile.java.html#025">View source</A>
@param
pStrPairs is an array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects whose String
representations will be used. The first of the two Strings is the String that will be replaced.
The second is the String that will replace the first.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void replaceRegex(Type1[][] pStrPairs) throws Exception
{
/*.
==========================================================================================
false is a dummy argument. It is not looked for. If it is not there in the argument list,
the Java compiler complains about the 2-dimentional array -- pStrPairs -- being passed as
the only memberof the variable argument list. Java thinks the 2D array *is* the variable
argument list.
------------------------------------------------------------------------------------------ */
this.modify("replaceRegex", pStrPairs, false);
}
/*: :METHOD:026:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is String replacement. It receives an argument that is an
array of 2-element arrays. Each 2-element array contains 2 Strings. The first String is a regular
expression to search for in this TextFile and the second String is a regular expression from which
the replacement is generated for each occurrence of the first String that is found.
<P><B>Implementation: </B><A HREF="TextFile.java.html#026">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: Type1[][] strPairs
<BLOCKQUOTE>
An array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects
whose String representations will be used. The first of the two strings is the String
that will be replaced. The second is the String that will replace the first.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
@SuppressWarnings("unchecked")
public <Type1> void replaceRegex(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
XString[][] strPairs = (XString[][])pArguments[0];
/*.
==========================================================================================
Read each line of this TextFile replacing all the substrings and writing the modified
lines to the pOutput file. The EOL that is lost when reading from a TextReader is
reattached so that replacement searches will work with EOL.
------------------------------------------------------------------------------------------ */
StringBuilder theWholeFile = new StringBuilder(UMath.ONE_MEG);
while (pIter.hasNext())
{
XString s = pIter.next();
s = s.trimRight();
s = s.concat("\n");
theWholeFile.append(s.toString());
}
XString wholeFile = new XString(theWholeFile.toString());
theWholeFile = null;
for (int i=0; i<strPairs.length; i++)
{
wholeFile = wholeFile.replaceAll(strPairs[i][0],strPairs[i][1]);
}
wholeFile = wholeFile.trimRight("\n");
pOutput.print(wholeFile);
}
/*: :METHOD:027:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method does a case-sensitive replacment of all instances of pOldString with pNewString
throughout this TextFile.<P>
This method repeatedly checks the resulting TextFile for occurrences of pOldString and replaces them
if they exist. The checking continues untill there are no occurrences of pOldString in the result.
The reason for this is to handle situations like this: say that thisFile = "AAA", pOldString = "AA",
and pNewString = "A". Running replace() one time would result in this TextFile: "AA". Running
iteratingReplace() one time would result in this TextFile: "A".
<P><B>Implementation: </B><A HREF="TextFile.java.html#027">View source</A>
@param
pOldString is the substring that will be replaced.
@param
pNewString is the XString that will replace the pOldString.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void iteratingReplace(Type1 pOldString, Type2 pNewString) throws Exception
{
this.iteratingReplace(pOldString,pNewString,true);
}
/*: :METHOD:028:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all instances of pOldString with pNewString throughout this TextFile.<P>
This method repeatedly checks the resulting TextFile for occurrences of pOldString and replaces them
if they exist. The checking continues untill there are no occurrences of pOldString in the result.
The reason for this is to handle situations like this: say that thisFile = "AAA", pOldString = "AA",
and pNewString = "A". Running replace() one time would result in this TextFile: "AA". Running
iteratingReplace() one time would result in this TextFile: "A".
<P><B>Implementation: </B><A HREF="TextFile.java.html#028">View source</A>
@param
pOldString is the substring that will be replaced.
@param
pNewString is the XString that will replace the pOldString.
@param
pCaseSensitive specifies whether or not to use case considerations. True means case sensitive,
false means case in-sensitive.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void iteratingReplace(Type1 pOldString, Type2 pNewString, boolean pCaseSensitive) throws Exception
{
XString[][] strPairs =
{
{XString.toXString(pOldString), XString.toXString(pNewString)}
};
this.iteratingReplace(strPairs,pCaseSensitive);
}
/*: :METHOD:029:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
For each pair of Strings in pStrPairs, this method does a case-sensitive replacment of all instances
of the first String in the pair with the second String in the pair throughout this TextFile.<P>
This method repeatedly checks the resulting TextFile for occurrences of the first String in each
pair and replaces them if they exist. The checking continues untill there are no occurrences of the
first String in each pair in the result. The reason for this is to handle situations like this: say
that thisFile = "AAA", the first String in a pair = "AA", and the second String in the pair = "A".
Running replace() one time would result in this TextFile: "AA". Running iteratingReplace() one time
would result in this TextFile: "A".
<P><B>Implementation: </B><A HREF="TextFile.java.html#029">View source</A>
@param
pStrPairs is an array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects whose String
representations will be used. The first of the two Strings is the String that will be replaced.
The second is the String that will replace the first.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void iteratingReplace(Type1[][] pStrPairs) throws Exception
{
this.iteratingReplace(pStrPairs, true);
}
/*: :METHOD:030:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
For each pair of Strings in pStrPairs, this method replaces all instances of the first String in the
pair with the second String in the pair throughout this TextFile.<P>
This method repeatedly checks the resulting TextFile for occurrences of the first String in each
pair and replaces them if they exist. The checking continues untill there are no occurrences of the
first String in each pair in the result. The reason for this is to handle situations like this: say
that thisFile = "AAA", the first String in a pair = "AA", and the second String in the pair = "A".
Running replace() one time would result in this TextFile: "AA". Running iteratingReplace() one time
would result in this TextFile: "A".
<P><B>Implementation: </B><A HREF="TextFile.java.html#030">View source</A>
@param
pStrPairs is an array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects whose String
representations will be used. The first of the two Strings is the String that will be replaced.
The second is the String that will replace the first.
@param
pCaseSensitive specifies whether or not to use case considerations. True means case sensitive,
false means case in-sensitive.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void iteratingReplace(Type1[][] pStrPairs, boolean pCaseSensitive) throws Exception
{
this.modify("iteratingReplace", pStrPairs, pCaseSensitive);
}
/*: :METHOD:031:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is String replacement. It receives an argument that is an
array of 2-element arrays. Each 2-element array contains 2 Strings. The first String is text to
search for in the input and the second String is a replacement for each occurrence of the first
String that is found.<P>
This method repeatedly checks the resulting TextFile for occurrences of the first String in each
pair and replaces them if they exist. The checking continues untill there are no occurrences of the
first String in each pair in the result. The reason for this is to handle situations like this: say
that thisFile = "AAA", the first String in a pair = "AA", and the second String in the pair = "A".
Running replace() one time would result in this TextFile: "AA". Running iteratingReplace() one time
would result in this TextFile: "A".
<P><B>Implementation: </B><A HREF="TextFile.java.html#031">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: Type1[][] strPairs
<BLOCKQUOTE>
An array of pairs of Objects that will be converted into their String
representations. That is, each element of the array contains an array of two Objects
whose String representations will be used. The first of the two strings is the String
that will be replaced. The second is the String that will replace the first.
</BLOCKQUOTE>
pArguments[1]: boolean caseSensitive
<BLOCKQUOTE>
A boolean that specifies whether or not to use case considerations. True means case
sensitive, false means case in-sensitive.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
@SuppressWarnings("unchecked")
public <Type1> void iteratingReplace(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
Type1[][] strPairs = (Type1[][])pArguments[0];
boolean caseSensitive = (boolean)pArguments[1];
/*.
==========================================================================================
Read each line of the source file replacing all the substrings and writing the modified
lines to the pOutput file. The EOL that is lost when reading from a TextReader is
reattached so that replacement searches will work with EOL.
------------------------------------------------------------------------------------------ */
StringBuilder theWholeFile = new StringBuilder(2 * UMath.ONE_MEG);
while (pIter.hasNext())
{
XString s = pIter.next();
s = s.trimRight();
s = s.concat("\n");
theWholeFile.append(s.toString());
}
XString wholeFile = new XString(theWholeFile.toString());
theWholeFile = null;
if (caseSensitive)
{
for (int i=0; i<strPairs.length; i++)
{
wholeFile = wholeFile.iteratingReplace(strPairs[i][0],strPairs[i][1]);
}
}
else
{
for (int i=0; i<strPairs.length; i++)
{
wholeFile = wholeFile.iteratingReplaceIgnoreCase(strPairs[i][0],strPairs[i][1]);
}
}
wholeFile = wholeFile.trimRight("\n");
pOutput.print(wholeFile);
}
/*: :METHOD:032:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method tabularizes the lines in this TextFile using the default delimiter -- spaces, and the
default separator between columns -- 2 spaces: " ".
<P><B>Implementation: </B><A HREF="TextFile.java.html#032">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void tabularize() throws Exception
{
this.tabularize(sDelimiters,sSeparator);
}
/*: :METHOD:033:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method tabularizes the lines in this TextFile using the default separator between columns -- 2
spaces: " ".
<P><B>Implementation: </B><A HREF="TextFile.java.html#033">View source</A>
@param
pDelimiters is the set of delimiters (the characters that separate tokens). Delimiter characters
themselves will not be treated as tokens.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void tabularize(Type1 pDelimiters) throws Exception
{
this.tabularize(pDelimiters,sSeparator);
}
/*: :METHOD:034:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method tabularizes the lines in this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#034">View source</A>
@param
pDelimiters is the set of delimiters (the characters that separate tokens). Delimiter characters
themselves will not be treated as tokens.
@param
pSeparator is the XString that is placed between the columns.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void tabularize(Type1 pDelimiters, Type2 pSeparator) throws Exception
{
XString delimiters = new XString(pDelimiters);
/*.
==========================================================================================
Read each line of the source file to determine the maximum width of each column in the
file
------------------------------------------------------------------------------------------ */
XStringsIterator iter = new XStringsIterator(this);
ArrayList<Integer> maxColumnWidths = new ArrayList<Integer>();
while (iter.hasNext())
{
XString xstr = iter.next();
ArrayList array = xstr.tokenizedString(delimiters);
for (int i=0; i<array.size(); i++)
{
XString chunk = (XString)array.get(i);
int len = chunk.length();
if (i == maxColumnWidths.size())
{
maxColumnWidths.add(new Integer(len));
}
else
{
int max = ((Integer)maxColumnWidths.get(i)).intValue();
if (len > max)
{
maxColumnWidths.set(i,new Integer(len));
}
}
}
}
/*.
==========================================================================================
Pass the column widths into a method that tabularizes.
------------------------------------------------------------------------------------------ */
this.modify("tabularize", pDelimiters, pSeparator, maxColumnWidths);
}
/*: :METHOD:035:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is tabularization. For example:
<BLOCKQUOTE>
If this TextFile comprises these lines:
<BLOCKQUOTE>
<PRE id="unindent">
1 22 333 4444 55555
1/22/333/4444/55555
11111 2222 333 44 5
1 22 333
</PRE>
</BLOCKQUOTE>
Then this code:
<BLOCKQUOTE>
<PRE id="unindent">
this.tabularize(" /", ",");
</PRE>
</BLOCKQUOTE>
Will create the file out.tmp to look like this:
<BLOCKQUOTE>
<PRE id="unindent">
1, 22, 333,4444,55555
1, 22, 333,4444,55555
11111,2222,333,44, 5
1, 22, 333
</PRE>
</BLOCKQUOTE>
And this code:
<BLOCKQUOTE>
<PRE id="unindent">
TextFile.tabularize("test.tmp", "out.tmp", " /", "---");
</PRE>
</BLOCKQUOTE>
Will create the file out.tmp to look like this:
<BLOCKQUOTE>
<PRE id="unindent">
1--- 22--- 333---4444---55555
1--- 22--- 333---4444---55555
11111---2222---333---44--- 5
1--- 22--- 333
</PRE>
</BLOCKQUOTE>
</BLOCKQUOTE>
Assuming the separator is "--|--" this algorithm will produce output like this"
<BLOCKQUOTE>
<PRE id="unindent">
1 --|--22 --|--333--|--4444--|--55555
1 --|--22 --|--333--|--4444--|--55555
11111--|--2222--|--333--|--44 --|--5
1 --|--22 --|--333--|-- --|--
</PRE>
</BLOCKQUOTE>
And this separator " | " will produce output like this"
<BLOCKQUOTE>
<PRE id="unindent">
1 | 22 | 333 | 4444 | 55555
1 | 22 | 333 | 4444 | 55555
11111 | 2222 | 333 | 44 | 5
1 | 22 | 333 | |
</PRE>
</BLOCKQUOTE>
<P><B>Implementation: </B><A HREF="TextFile.java.html#035">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: XString delimiters
<BLOCKQUOTE>
Is an Object whose XString representation is the set of delimiters (the characters
that separate tokens). Delimiter characters themselves will not be treated as tokens.
</BLOCKQUOTE>
pArguments[1]: XString separator
<BLOCKQUOTE>
Is an Object whose XString representation is used to separate the columns in the
output.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
@SuppressWarnings("unchecked")
public void tabularize(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
XString delimiters = new XString(pArguments[0]);
XString separator = new XString(pArguments[1]);
ArrayList<Integer> colWidths = (ArrayList<Integer>)(pArguments[2]);
int colCount = colWidths.size();
/*.
==========================================================================================
Read each line of the source file again and write a tabularized version of it to the
pOutput file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
/*.
==========================================================================================
Get the next line from the file and split it up into delimeters-separated chunks
------------------------------------------------------------------------------------------ */
XString line = pIter.next();
ArrayList<XString> chunks = line.tokenizedString(delimiters);
int chunkCount = chunks.size();
/*.
==========================================================================================
If this row is missing chunks for any columns, add them to the row as empty chunks
------------------------------------------------------------------------------------------ */
while (chunkCount < colCount)
{
chunks.add(XString.EMPTY);
chunkCount++;
}
/*.
==========================================================================================
Write each chunk out separated from its succeeding chunk with the separator
------------------------------------------------------------------------------------------ */
for (int i=0; i<chunkCount; i++)
{
/*.
==========================================================================================
Get the next chunk and its column width
------------------------------------------------------------------------------------------ */
XString chunk = (XString)chunks.get(i);
int colWidth = ((Integer)colWidths.get(i)).intValue();
/*.
==========================================================================================
If this chunk is not the one in the last column, widen it to the column width and concat
the separator to it and write it
------------------------------------------------------------------------------------------ */
if (i < (colCount - 1))
{
chunk = chunk.alignLeft(colWidth, ' ').concat(separator);
pOutput.print(chunk);
}
/*.
==========================================================================================
If this chunk is the one in the last column, don't widen it or concat the separator to it.
Instead, effectivly concat an end of line to it and write it out.
------------------------------------------------------------------------------------------ */
else
{
pOutput.println(chunk);
}
}
}
}
/*: :METHOD:036:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the tabs in this TextFile with the appropriate number of spaces using the
default tab size -- 3.
<P><B>Implementation: </B><A HREF="TextFile.java.html#036">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void detab() throws Exception
{
this.detab(sTabSize);
}
/*: :METHOD:037:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the tabs in this TextFile with the appropriate number of spaces.
<P><B>Implementation: </B><A HREF="TextFile.java.html#037">View source</A>
@param
pTabSize is the number of spaces between tab stops.
*//*
---------------------------------------------------------------------------------------------------- */
public void detab(int pTabSize) throws Exception
{
this.modify("detab", pTabSize);
}
/*: :METHOD:038:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is tab replacement. It replaces all the tabs in a file with
the appropriate number of spaces.
<P><B>Implementation: </B><A HREF="TextFile.java.html#038">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: int tabSize
<BLOCKQUOTE>
Is the number of spaces between tab stops.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void detab(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
int tabSize = (int)pArguments[0];
/*.
==========================================================================================
Read each line of the source file and write a detabed version of it to the output file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
pOutput.println(pIter.next().detab(tabSize));
}
}
/*: :METHOD:039:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the spaces in this TextFile with the appropriate number of tabs.
<P><B>Implementation: </B><A HREF="TextFile.java.html#039">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void entab() throws Exception
{
this.entab(sTabSize);
}
/*: :METHOD:040:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the spaces in this TextFile with the appropriate number of tabs.
<P><B>Implementation: </B><A HREF="TextFile.java.html#040">View source</A>
@param
pTabSize is the number of spaces between tab stops.
*//*
---------------------------------------------------------------------------------------------------- */
public void entab(int pTabSize) throws Exception
{
this.modify("entab", pTabSize);
}
/*: :METHOD:041:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is space replacement. It replaces spaces in a file with the
appropriate number of tabs.
<P><B>Implementation: </B><A HREF="TextFile.java.html#041">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: int tabSize
<BLOCKQUOTE>
Is the number of spaces between tab stops.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void entab(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
int tabSize = (int)pArguments[0];
/*.
==========================================================================================
Read each line of the source file and write a entabed version of it to the output file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
pOutput.println(pIter.next().entab(tabSize));
}
}
/*: :METHOD:042:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the tabs in this TextFile with the appropriate number of spaces using the
default tab size -- 3 and trims any whitespace from the end of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#042">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void detabAndTrim() throws Exception
{
/*.
==========================================================================================
DetabAndTrim the file
------------------------------------------------------------------------------------------ */
this.detabAndTrim(sTabSize);
}
/*: :METHOD:043:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the tabs in this TextFile with the appropriate number of spaces and trims
any whitespace from the end of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#043">View source</A>
@param
pTabSize is the number of spaces between tab stops.
*//*
---------------------------------------------------------------------------------------------------- */
public void detabAndTrim(int pTabSize) throws Exception
{
this.modify("detabAndTrim", pTabSize);
}
/*: :METHOD:044:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is space replacement and trailing whitespace reoval. It
replaces spaces in a file with the appropriate number of tabs and deletes any trailing whitespace
from the line.
<P><B>Implementation: </B><A HREF="TextFile.java.html#044">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: int tabSize
<BLOCKQUOTE>
Is the number of spaces between tab stops.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void detabAndTrim(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
int tabSize = (int)pArguments[0];
/*.
==========================================================================================
Read each line of the source file and write a entabed version of it to the output file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
pOutput.println(pIter.next().detab(tabSize).trimRight());
}
}
/*: :METHOD:045:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the spaces in this TextFile with the appropriate number of tabs using the
default tab size -- 3 and trims any whitespace from the end of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#045">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void entabAndTrim() throws Exception
{
/*.
==========================================================================================
DetabAndTrim the file
------------------------------------------------------------------------------------------ */
this.entabAndTrim(sTabSize);
}
/*: :METHOD:046:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method replaces all the spaces in this TextFile with the appropriate number of tabs and trims
any whitespace from the end of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#046">View source</A>
@param
pTabSize is the number of spaces between tab stops.
*//*
---------------------------------------------------------------------------------------------------- */
public void entabAndTrim(int pTabSize) throws Exception
{
this.modify("entabAndTrim", pTabSize);
}
/*: :METHOD:047:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is space replacement and trailing whitespace reoval. It
replaces spaces in a file with the appropriate number of tabs and deletes any trailing whitespace
from the line.
<P><B>Implementation: </B><A HREF="TextFile.java.html#047">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: int tabSize
<BLOCKQUOTE>
Is the number of spaces between tab stops.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void entabAndTrim(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
int tabSize = (int)pArguments[0];
/*.
==========================================================================================
Read each line of the source file and write a entabed version of it to the output file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
pOutput.println(pIter.next().entab(tabSize).trimRight());
}
}
/*: :METHOD:048:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method trims any whitespace from the end of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#048">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void trimRight() throws Exception
{
this.modify("trimRight");
}
/*: :METHOD:049:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it trims any trailing whitespace from the end of each line.
<P><B>Implementation: </B><A HREF="TextFile.java.html#049">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
This method uses no arguments passed through pArguments.
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void trimRight(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Read each line of the source file and write a trimmed version of it to the output file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
pOutput.println(pIter.next().trimRight());
}
}
/*: :METHOD:050:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method trims any whitespace from the beginning of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#050">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void trimLeft() throws Exception
{
this.modify("trimLeft");
}
/*: :METHOD:051:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method does a case-sensitive removal of a substring from the beginning of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#051">View source</A>
@param
pPrefix is the substring that will be trimmed from the beginning of the lines.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void trimLeft(Type1 pPrefix) throws Exception
{
trimLeft(pPrefix, true);
}
/*: :METHOD:052:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method removes of a substring from the beginning of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#052">View source</A>
@param
pPrefix is the substring that will be trimmed from the beginning of the lines.
@param
pCaseSensitive specifies whether or not to use case considerations. True means case sensitive,
false means not case sensitive.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void trimLeft(Type1 pPrefix, boolean pCaseSensitive) throws Exception
{
this.modify("trimLeft", pPrefix, pCaseSensitive);
}
/*: :METHOD:053:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it trim either a substring or all the leading whitespace
from the start of each line.
If an argument is passed in, this method trims the string representation of it from the beginning
of each line. If no argument is passed in, this method trims all whitespace from the beginning of
each line.
<P><B>Implementation: </B><A HREF="TextFile.java.html#053">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: [optional] XString pPrefix
<BLOCKQUOTE>
If this optional argument is passed in, its string representation is removed from the
beginning of each line where it is present. If the optional argument is not passed
in, all the leading whitespace is removed from the beginning of each line.
</BLOCKQUOTE>
pArguments[1]: [optional] boolean caseSensitive
<BLOCKQUOTE>
A boolean that specifies whether or not to use case considerations. True means case
sensitive, false means not case sensitive. If this argument is not passed in, the
default is case sensitive.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void trimLeft(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
If an argument was passed in, trim the XString representation of it from the beginning of
each line. If no argument was passed in, trim all whitespace from the beginning of each
line.
------------------------------------------------------------------------------------------ */
if (pArguments.length > 0)
{
XString prefix = new XString(pArguments[0]);
/*.
==========================================================================================
If a second argument was passed in, it is a boolean (or better be) that tells us whether
or not to make case distinctions when looking for substring matches at the beginning of
each line. The default is: true - make case distinctions.
------------------------------------------------------------------------------------------ */
boolean caseSensitive = true;
if (pArguments.length > 1)
{
caseSensitive = (boolean)pArguments[1];
}
if (caseSensitive)
{
while (pIter.hasNext())
{
pOutput.println(pIter.next().trimLeft(prefix));
}
}
else
{
while (pIter.hasNext())
{
pOutput.println(pIter.next().trimLeftIgnoreCase(prefix));
}
}
}
/*.
==========================================================================================
No prefix was supplied through the parameters so default to removing all leading
whitespace from each line.
------------------------------------------------------------------------------------------ */
else
{
while (pIter.hasNext())
{
pOutput.println(pIter.next().trimLeft());
}
}
}
/*: :METHOD:054:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method trims any whitespace from the beginning and end of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#054">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void trim() throws Exception
{
this.modify("trim");
}
/*: :METHOD:055:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it trims any leading or trailing whitespace from the start
and end of each line.
<P><B>Implementation: </B><A HREF="TextFile.java.html#055">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
This method uses no arguments passed through pArguments.
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void trim(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Read each line of the source file and write a trimmed version of it to the pOutput file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
pOutput.println(pIter.next().trim());
}
}
/*: :METHOD:056:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method removes all blank lines from the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#056">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void tossBlankLines() throws Exception
{
this.modify("tossBlankLines");
}
/*: :METHOD:057:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is that it removes all the blank lines from the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#057">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
This method uses no arguments passed through pArguments.
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void tossBlankLines(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Read each line of the source file and write a tossed version of it to the pOutput file.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
XString line = pIter.next();
if ( ! line.isEmpty())
{
pOutput.println(line);
}
}
}
/*: :METHOD:058:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method sorts the lines in a file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#058">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void sort() throws Exception
{
this.modify("sort");
}
/*: :METHOD:059:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it sorts the lines of the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#059">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
This method uses no arguments passed through pArguments.
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void sort(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Read each line of the source file into an array of strings
------------------------------------------------------------------------------------------ */
ArrayList<XString> strings = new ArrayList<XString>();
while (pIter.hasNext())
{
strings.add(pIter.next());
}
/*.
==========================================================================================
Sort the array of strings
------------------------------------------------------------------------------------------ */
strings = (ArrayList<XString>)Util.sortedArrayList(strings);
/*.
==========================================================================================
Write each XString from the sorted array into the pOutput file.
------------------------------------------------------------------------------------------ */
XStringsIterator sIter = new XStringsIterator(strings);
while (sIter.hasNext())
{
pOutput.println(sIter.next());
}
}
/*: :METHOD:060:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method dedups the lines in a file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#060">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void dedup() throws Exception
{
this.modify("dedup");
}
/*: :METHOD:061:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over ·this· TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it removes duplicate lines from the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#061">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
This method uses no arguments passed through pArguments.
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void dedup(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Read each line of the source file and compare it to all the other lines read. If it is the
same as any of the others, throw it out, otherwise, write it to the output.
------------------------------------------------------------------------------------------ */
HashSet<XString> linesSeen = new HashSet<XString>();
while (pIter.hasNext())
{
XString line = pIter.next();
if ( ! linesSeen.contains(line))
{
pOutput.println(line);
linesSeen.add(line);
}
}
}
/*: :METHOD:062:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method removes newlines from a file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#062">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void removeNewlines() throws Exception
{
this.modify("removeNewlines");
}
/*: :METHOD:063:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it removes all the newlines from the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#063">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
This method uses no arguments passed through pArguments.
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void removeNewlines(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Read each line of the source file and write it out without a newline
------------------------------------------------------------------------------------------ */
XString line = null;
while (pIter.hasNext())
{
line = pIter.next();
pOutput.print(line);
}
}
/*: :METHOD:064:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method adds a prefix string to the beginning of each line in this file
<P><B>Implementation: </B><A HREF="TextFile.java.html#064">View source</A>
@param
pPrefix is the Object whose string representation is added as a prefix to each line.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void prefixLines(Type1 pPrefix) throws Exception
{
XString prefix = new XString(pPrefix);
this.modify("prefixLines", prefix);
}
/*: :METHOD:065:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it adds a prefix string to the beginning of each line in
this file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#065">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: XString pPrefix
<BLOCKQUOTE>
pPrefix is the Object whose string representation is added as a prefix to each line.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void prefixLines(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
XString prefix = new XString(pArguments[0]);
/*.
==========================================================================================
Read each line of the source file and write it out with it prefix
------------------------------------------------------------------------------------------ */
XString line = null;
while (pIter.hasNext())
{
line = prefix.concat(pIter.next());
pOutput.println(line);
}
}
/*: :METHOD:066:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method adds a string (which of course, may include newlines) to the beginning of this file.<P>
This method is equivalent to insertIntoFile(pStr, 1), where 1 is the number of the first line of
this file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#066">View source</A>
@param
pStr is the Object whose string representation is prepended to this file.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void prependToFile(Type1 pStr) throws Exception
{
this.insertIntoFile(pStr, 1);
}
/*: :METHOD:067:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method inserts a string (which of course, may include newlines) into a this file immediately
preceeding the specified line. If the line number specified is greater than the number of lines in
this file, the string will be written to the end of the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#067">View source</A>
@param
pStr is the Object whose string representation is inserted into this file.
@param
pLineNumber is the line number immediately prior to which the string is inserted into this file.
If the line number specified is greater than the number of lines in this file, the string will
be written to the end of the file.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void insertIntoFile(Type1 pStr, int pLineNumber) throws Exception
{
XString str = new XString(pStr);
this.modify("insertIntoFile", str, pLineNumber);
}
/*: :METHOD:068:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method reads Strings from an iterator over this TextFile (pIter), modifies them, and writes
them out to an output (pOutput).<P>
The modification this method performs is it inserts a string (which of course, may include newlines)
into a this file immediately preceeding a specified line. If the line number specified is greater
than the number of lines in this file, the string will be written to the end of the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#068">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: XString pStr
<BLOCKQUOTE>
pStr is the string that is inserted into this file.
</BLOCKQUOTE>
pArguments[1]: int pLineNumber
<BLOCKQUOTE>
pLineNumber is the line number immediately prior to which the string is inserted into
this file. If the line number specified is greater than the number of lines in this
file, the string will be written to the end of the file.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void insertIntoFile(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
XString str = new XString(pArguments[0]);
int lineNumber = (int)pArguments[1];
/*.
==========================================================================================
Read each line of the source file and write it back out, inserting the string where
required.
------------------------------------------------------------------------------------------ */
boolean inserted = false;
int lineCount = 1;
while (pIter.hasNext())
{
if (lineCount++ == lineNumber)
{
pOutput.println(str);
pOutput.println(pIter.next());
inserted = true;
break;
}
pOutput.println(pIter.next());
}
while (pIter.hasNext())
{
pOutput.println(pIter.next());
}
if (!inserted)
{
pOutput.println(str);
}
}
/*: :METHOD:069:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method searches this TextFile for a start delimiter. Each time one is located, it finds its
corresponding end delimiter and then once found, deletes the start delimiter, end delimiter, and
everything in between.
<P><B>Implementation: </B><A HREF="TextFile.java.html#069">View source</A>
@param
pStartDelimiter is the start delimiter that delimits the start of sections of the file to delete.
@param
pEndDelimiter is the end delimiter that delimits the end of sections of the file to delete.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void stripDelimitedSubstrings(Type1 pStartDelimiter, Type2 pEndDelimiter) throws Exception
{
stripDelimitedSubstrings(pStartDelimiter, pEndDelimiter, true, true);
}
/*: :METHOD:070:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method searches this TextFile for a start delimiter. Each time one is located, it finds its
corresponding end delimiter and then once found, deletes the start delimiter, end delimiter, and
everything in between.
<P><B>Implementation: </B><A HREF="TextFile.java.html#070">View source</A>
@param
pStartDelimiter is the start delimiter that delimits the start of sections of the file to delete.
@param
pEndDelimiter is the end delimiter that delimits the end of sections of the file to delete.
@param
pDeleteTerminalNewline tells this method whether or not to strip out newlines that happen to be
the endDelimiter. It is a concession to source code file comment stripping. A "to end of line"
comment type such as the double forward slash in c-type languages or the single quote in
basic-type languages uses the newline as a comment terminator (endDelimiter). Stripping these out
of the file ruins the formatting of these kinds of files. So pDeleteTerminalNewline is provided
to short-circuit the stripping of them if desired. Normally, as the endDelimiter, they would be
stripped, but if this parameter is set to 'false', they are not stripped out.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void stripDelimitedSubstrings(Type1 pStartDelimiter, Type2 pEndDelimiter, boolean pDeleteTerminalNewline) throws Exception
{
stripDelimitedSubstrings(pStartDelimiter, pEndDelimiter, pDeleteTerminalNewline, true);
}
/*: :METHOD:071:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method searches this TextFile for a start delimiter. Each time one is located, it finds its
corresponding end delimiter and then once found, deletes the start delimiter, end delimiter, and
everything in between.
<P><B>Implementation: </B><A HREF="TextFile.java.html#071">View source</A>
@param
pStartDelimiter is the start delimiter that delimits the start of sections of the file to delete.
@param
pEndDelimiter is the end delimiter that delimits the end of sections of the file to delete.
@param
pDeleteTerminalNewline tells this method whether or not to strip out newlines that happen to be
the endDelimiter. It is a concession to source code file comment stripping. A "to end of line"
comment type such as the double forward slash in c-type languages or the single quote in
basic-type languages uses the newline as a comment terminator (endDelimiter). Stripping these out
of the file ruins the formatting of these kinds of files. So pDeleteTerminalNewline is provided
to short-circuit the stripping of them if desired. Normally, as the endDelimiter, they would be
stripped, but if this parameter is set to 'false', they are not stripped out.
@param
pRecurse tells this method whether or not to recognize nested delimited substrings. If this is
set to true, then nested substrings are recursively processes and therefor require their own
endDelimiter. This parameter is also usually needed for source code file comment processing. A
"to end of line" comment type such as the double forward slash in c-type languages or the single
quote in basic-type languages uses the newline as a comment terminator (endDelimiter). If a
double forward slash or single quote is embedded in the string befor the terminating newline of
the the first startDelimiter, then there is not a matching newline for both startDelimiters. So
recursively processing the second startDelimiter would lead to bizzar results as second
startDelimiter would "eat" the first startDelimiter's corresponding endDelimiter. This in turn
would cause this method to continue eating characters (inappropriately) on behalf of the first
startDelimiter until another newline was encountered. So pRecurse is provided to short-circuit
the processing of nested "to-end-of-line" comments if desired.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1,Type2> void stripDelimitedSubstrings(Type1 pStartDelimiter, Type2 pEndDelimiter, boolean pDeleteTerminalNewline, boolean pRecurse) throws Exception
{
this.modify("stripDelimitedSubstrings", pStartDelimiter, pEndDelimiter, pDeleteTerminalNewline, pRecurse);
}
/*: :METHOD:072:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method repeatedly searches the file for a start delimiter. Each time one is located, it finds
its corresponding end delimiter and then once found, deletes the start delimiter, end delimiter, and
everything in between.
<P><B>Implementation: </B><A HREF="TextFile.java.html#072">View source</A>
@param
pFileIn is the name of the file that will be copied to the output file with lines sorted.
pFileOut must not be the same as pFileIn. PFileOut and pFileIn must not be null.
@param
pFileOut is the name that will be given to the file that is produced. PFileOut must not be the
same as pFileIn. PFileOut and pFileIn must not be null.
@param
pStartDelimiter is the start delimiter that delimits the start of sections of the file to delete.
@param
pEndDelimiter is the end delimiter that delimits the end of sections of the file to delete.
@param
pDeleteTerminalNewline tells this method whether or not to strip out newlines that happen to be
the endDelimiter. It is a concession to source code file comment stripping. A "to end of line"
comment type such as the double forward slash in c-type languages or the single quote in
basic-type languages uses the newline as a comment terminator (endDelimiter). Stripping these out
of the file ruins the formatting of these kinds of files. So pDeleteTerminalNewline is provided
to short-circuit the stripping of them if desired. Normally, as the endDelimiter, they would be
stripped, but if this parameter is set to 'false', they are not stripped out.
@param
pRecurse tells this method whether or not to recognize nested delimited substrings. If this is
set to true, then nested substrings are recursively processes and therefor require their own
endDelimiter. This parameter is also usually needed for source code file comment processing. A
"to end of line" comment type such as the double forward slash in c-type languages or the single
quote in basic-type languages uses the newline as a comment terminator (endDelimiter). If a
double forward slash or single quote is embedded in the string befor the terminating newline of
the the first startDelimiter, then there is not a matching newline for both startDelimiters. So
recursively processing the second startDelimiter would lead to bizzar results as second
startDelimiter would "eat" the first startDelimiter's corresponding endDelimiter. This in turn
would cause this method to continue eating characters (inappropriately) on behalf of the first
startDelimiter until another newline was encountered. So pRecurse is provided to short-circuit
the processing of nested "to-end-of-line" comments if desired.
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: int tabSize
<BLOCKQUOTE>
</BLOCKQUOTE>
pArguments[1]: XString pStartDelimiter
<BLOCKQUOTE>
Is the start delimiter that delimits the start of sections of the file to delete.
</BLOCKQUOTE>
pArguments[2]: XString endDelimiter
<BLOCKQUOTE>
Is the end delimiter that delimits the end of sections of the file to delete.
</BLOCKQUOTE>
pArguments[3]: boolean deleteTerminalNewline
<BLOCKQUOTE>
Tells this method whether or not to strip out newlines that happen to be the
endDelimiter. It is a concession to source code file comment stripping. A "to end of
line" comment type such as the double forward slash in c-type languages or the single
quote in basic-type languages uses the newline as a comment terminator
(endDelimiter). Stripping these out of the file ruins the formatting of these kinds
of files. So pDeleteTerminalNewline is provided to short-circuit the stripping of
them if desired. Normally, as the endDelimiter, they would be stripped, but if this
parameter is set to 'false', they are not stripped out.
</BLOCKQUOTE>
pArguments[4]: boolean recurse
<BLOCKQUOTE>
Tells this method whether or not to recognize nested delimited substrings. If this is
set to true, then nested substrings are recursively processes and therefor require
their own endDelimiter. This parameter is also usually needed for source code file
comment processing. A "to end of line" comment type such as the double forward slash
in c-type languages or the single quote in basic-type languages uses the newline as a
comment terminator (endDelimiter). If a double forward slash or single quote is
embedded in the string befor the terminating newline of the the first startDelimiter,
then there is not a matching newline for both startDelimiters. So recursively
processing the second startDelimiter would lead to bizzar results as second
startDelimiter would "eat" the first startDelimiter's corresponding endDelimiter.
This in turn would cause this method to continue eating characters (inappropriately)
on behalf of the first startDelimiter until another newline was encountered. So
pRecurse is provided to short-circuit the processing of nested "to-end-of-line"
comments if desired.
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void stripDelimitedSubstrings(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
XString startDelimiter = new XString(pArguments[0]);
XString endDelimiter = new XString(pArguments[1]);
boolean deleteTerminalNewline = (boolean)pArguments[2];
boolean recurse = (boolean)pArguments[3];
/*.
==========================================================================================
Read each line of the source file into a StringBuffer. The EOL that is lost when reading
from a TextReader is reattached so that searches will work with \n.
------------------------------------------------------------------------------------------ */
StringBuffer theWholeFile = new StringBuffer(2 * UMath.ONE_MEG);
while (pIter.hasNext())
{
XString s = pIter.next();
s = s.trimRight();
s = s.concat("\n");
theWholeFile.append(s.toString());
}
/*.
==========================================================================================
DeleteTerminalNewline is a concession to source code file comment stripping. A "to end of
line" comment type such as the double forward slash in c-type languages or the single
quote in basic-type languages uses the \n as a comment terminator (endDelimiter).
Stripping these out of the file ruins the formatting of these kinds of files. So
deleteTerminalNewline is provided to short-circuit the stripping of them if desired.
Normally, as the endDelimiter, they would be stripped, but if this parameter is set to
'false', they are not stripped out.
------------------------------------------------------------------------------------------ */
int minusNewline = ((! deleteTerminalNewline) && (endDelimiter.endsWith("\n")))? 1 : 0;
/*.
==========================================================================================
Repeatedly search the StringBuffer for the start delimiter. Each time one is located, find
its corresponding end delimiter. Once found, delete the start delimiter, end delimiter,
and everything in between.
------------------------------------------------------------------------------------------ */
int startDelimiterIdx;
while ((startDelimiterIdx = theWholeFile.indexOf(startDelimiter.toString())) != (-1))
{
int idxAfterComment = (int)UString.indexAfterDelimitedSpan(theWholeFile, startDelimiter, endDelimiter, startDelimiterIdx + startDelimiter.length(), recurse);
theWholeFile = theWholeFile.delete(startDelimiterIdx, idxAfterComment - minusNewline);
}
/*.
==========================================================================================
Write out the StringBuffer object to the pOutput file
------------------------------------------------------------------------------------------ */
pOutput.print(theWholeFile.toString());
}
/*: :METHOD:073:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method indents a delimited block starting at the current line containing a start delimiter and
continuing until it has indented the line containing the matching end delimiter.
<P><B>Implementation: </B><A HREF="TextFile.java.html#073">View source</A>
@param
pStartDelimiter is the XString that demarcates the start of the block of text to indent.
@param
pEndDelimiter is the XString that demarcates the end of the block of text to indent.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1, Type2> void indentDelimitedBlockFromPriorText(Type1 pStartDelimiter, Type2 pEndDelimiter) throws Exception
{
this.modify("indentDelimitedBlockFromPriorText", pStartDelimiter, pEndDelimiter);
}
/*: :METHOD:074:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method indents a delimited block starting at the current line containing a start delimiter and
continuing until it has indented the line containing the matching end delimiter.
<P><B>Implementation: </B><A HREF="TextFile.java.html#074">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments. It is where pStartDelimiter and pEndDelimiter
are placed.
*//*
---------------------------------------------------------------------------------------------------- */
public void indentDelimitedBlockFromPriorText(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Convert the generic parameter types to XString
------------------------------------------------------------------------------------------ */
XString startDelimiter = new XString(pArguments[0]);
XString endDelimiter = new XString(pArguments[1]);
/*.
==========================================================================================
For keeping track of the indent of the last non-blank line.
------------------------------------------------------------------------------------------ */
XString lastIndent = new XString("");
/*.
==========================================================================================
For each line of the file, if it is a start delimiter, call out to indent it along with
its subordinate lines and matching end delimiter. Otherwise, just send it to output.
------------------------------------------------------------------------------------------ */
int currentLineNumber = 0;
while (pIter.hasNext())
{
currentLineNumber++;
/*.
==========================================================================================
Get the next line from the file, its whitespace prefix and a trimmed version of it.
------------------------------------------------------------------------------------------ */
XString currentLine = pIter.next();
XString currentIndent = currentLine.whitespacePrefix();
XString currentTrimmed = currentLine.trim();
/*.
==========================================================================================
If this line is a start delimiter, indent it, everything subordinate to it, and its
matching end delimiter.
------------------------------------------------------------------------------------------ */
if (currentTrimmed.equals(startDelimiter))
{
currentLineNumber = this.indentDelimitedBlockFromPriorText(pIter, pOutput, startDelimiter, endDelimiter, currentLineNumber, currentLine, lastIndent);
}
/*.
==========================================================================================
Otherwise, it's just a normal line so send it to the output unchanged and keep track of
the indent of the last nonblank line.
------------------------------------------------------------------------------------------ */
else
{
pOutput.println(currentLine);
if (! currentTrimmed.isEmpty())
{
lastIndent = currentIndent;
}
}
}
}
/*: :METHOD:075:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method is the recursive part of the method that indents a delimited block starting at the
current line containing a start delimiter and continuing until it has indented the line containing
the matching end delimiter.
<P><B>Implementation: </B><A HREF="TextFile.java.html#075">View source</A>
@return
This method returns the line number of the last line it sent to pOutput.
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pStartDelimiter is the XString that demarcates the start of the block of text to indent.
@param
pEndDelimiter is the XString that demarcates the end of the block of text to indent.
@param
pCurrentLineNumber is the line number from the input file of the pCurrentLine
@param
pCurrentLine is the current line from the input file and it is expected to consist of a start
delimiter.
@param
pIndentFrom is the indentation of the last non-blank line in the file prior to pCurrentLine.
*//*
---------------------------------------------------------------------------------------------------- */
private int indentDelimitedBlockFromPriorText(XStringsIterator pIter, TextWriter pOutput, XString pStartDelimiter, XString pEndDelimiter, int pCurrentLineNumber, XString pCurrentLine, XString pIndentFrom) throws Exception
{
/*.
==========================================================================================
This is how far in the delimited block should be indented from the prior non-blank line of
text.
------------------------------------------------------------------------------------------ */
XString oneIndent = new XString(" ");
/*.
==========================================================================================
This is the extra indentation characters that will be prepended to every line in the
delimited block to insure that each is indented the right amount from the prior non-blank
line of text
------------------------------------------------------------------------------------------ */
XString extraIndent = new XString("");
/*.
==========================================================================================
When we arrive in this method, a start delimiter has been found on the current line and
that current line was passed into this method without being output. Now set all the local
line variables to represent this incomming start delimiter line.
------------------------------------------------------------------------------------------ */
XString currentLine = pCurrentLine;
XString currentLineIndent = currentLine.whitespacePrefix();
XString currentLineTrimmed = currentLine.trim();
/*.
==========================================================================================
If this start delimiter line is not indented more than pIndentFrom, then figure out how
much additional indent is needed to be one indent level further in than pIndentFrom and
change extraIndent to be of that length of space characters.
------------------------------------------------------------------------------------------ */
if (currentLineIndent.length() < pIndentFrom.length() + oneIndent.length())
{
int amountOfExtraIndent = pIndentFrom.length() + oneIndent.length() - currentLineIndent.length();
extraIndent = XString.fill(amountOfExtraIndent, ' ');
}
/*.
==========================================================================================
Now increment the current line number and output the currentLine with any required extra
indent characters prepended to it.
------------------------------------------------------------------------------------------ */
int currentLineNumber = pCurrentLineNumber;
currentLine = extraIndent.concat(currentLine);
currentLineIndent = currentLine.whitespacePrefix();
currentLineTrimmed = currentLine.trim();
pOutput.println(currentLine);
/*.
==========================================================================================
Now we just start reading each suceeding line, prepending the extra indent characters to
each one and sending it to output. When we run into the matching end delimiter, we stop
reading, and go through the same exercise for indenting it that we went through with its
corresponding start delimiter so we can output it with the proper indentation. (We don't
just prepend the extra indentation just in case the end delimiter is not lined up properly
in the input file with its start delimiter.) If we run into another start delimiter before
hitting the end delimiter, that means there is a nested delimited block. That scenario is
handled via recursion.
------------------------------------------------------------------------------------------ */
boolean endFound = false;
XString lastIndent = currentLineIndent;
while (pIter.hasNext())
{
currentLineNumber++;
/*.
==========================================================================================
Get the next line from the file, its whatespace prefix and a trimmed version of it.
------------------------------------------------------------------------------------------ */
currentLine = pIter.next();
currentLineIndent = currentLine.whitespacePrefix();
currentLineTrimmed = currentLine.trim();
/*.
==========================================================================================
THIS BLOCK IS THE ONLY NORMAL WAY OUT OF THIS METHOD.
Since we came into this method because a start delimiter was found, the only legitimate
way out of the methhod is here - when a matching end delimiter is found. Output it with
the proper indentation to line up with the start delimiter and return the current line
count.
------------------------------------------------------------------------------------------ */
endFound = currentLineTrimmed.equals(pEndDelimiter);
if (endFound)
{
/*.
==========================================================================================
If this end delimiter line is not indented more than pIndentFrom, then figure out how much
additional indent is needed to be one indent level further in than pIndentFrom and change
extraIndent to be of that length of space characters.
------------------------------------------------------------------------------------------ */
if (currentLineIndent.length() < pIndentFrom.length() + oneIndent.length())
{
int amountOfExtraIndent = pIndentFrom.length() + oneIndent.length() - currentLineIndent.length();
extraIndent = XString.fill(amountOfExtraIndent, ' ');
}
/*.
==========================================================================================
Now output the currentLine with any required extra indent characters prepended to it.
------------------------------------------------------------------------------------------ */
currentLine = extraIndent.concat(currentLine);
pOutput.println(currentLine);
/*.
==========================================================================================
And return the current line number
------------------------------------------------------------------------------------------ */
return currentLineNumber;
}
/*.
==========================================================================================
Otherwise, if we run into another start delimiter before we find the matching end
delimiter for the start delimiter that was passed into this method, it means we have
encountered a nested start delimiter. Pass it into a recursive call to this method for
processing.
------------------------------------------------------------------------------------------ */
else if (currentLineTrimmed.equals(pStartDelimiter))
{
currentLineNumber = this.indentDelimitedBlockFromPriorText(pIter, pOutput, pStartDelimiter, pEndDelimiter, currentLineNumber, currentLine, lastIndent);
}
/*.
==========================================================================================
Otherwise, prepend the currenty extra indentation to the current line and send it to
output.
------------------------------------------------------------------------------------------ */
else
{
currentLine = extraIndent.concat(currentLine);
currentLineIndent = currentLine.whitespacePrefix();
currentLineTrimmed = currentLine.trim();
pOutput.println(currentLine);
/*.
==========================================================================================
Keep track of the indent of the last nonblank line.
------------------------------------------------------------------------------------------ */
if (! currentLineTrimmed.isEmpty())
{
lastIndent = currentLineIndent;
}
}
}
/*.
==========================================================================================
If we get here, we got to the end of file and the start/end delimiters didn't all match up
so throw an exception
------------------------------------------------------------------------------------------ */
throw new Exception("TextFile.indentDelimitedBlockFromPriorText(): " + pStartDelimiter + " delimiter on line " + pCurrentLineNumber + " is unmatched");
}
/*: :METHOD:076:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method repairs lines where a start or end delimiter got placed (most likely by word wrapping)
at the beginning or ending of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#076">View source</A>
@param
pStartDelimiter is the start delimiter.
@param
pEndDelimiter is the end delimiter.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1, Type2> void unwrapBlockDelimiters(Type1 pStartDelimiter, Type2 pEndDelimiter) throws Exception
{
/*.
==========================================================================================
The return value from modify indicates whether or not this pass through the file found any
block delimiters that needed to be unwrapped. This method can only find one instance of a
wrapped delimiter per line on each pass through the file. If there are multiple instances
on single lines, they can only be resolved by calling this method repeatedly until they
are all resolved. If the method returns true, it means that a delimiter that had to be
unwrapped was found and that another pass needs to be made through the file to see if
there are any more on the lines on which one was found and resolved. When this method
returns false, it means all instances of wrapped delimeters on all lines have been
resolved.
------------------------------------------------------------------------------------------ */
while (this.modify("unwrapBlockDelimiters", pStartDelimiter, pEndDelimiter));
}
/*: :METHOD:077:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method repairs lines where a start or end delimiter got placed (most likely by word wrapping)
at the beginning or ending of the lines.
<P><B>Implementation: </B><A HREF="TextFile.java.html#077">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments. It is where pStartDelimiter and pEndDelimiter
are placed.
*//*
---------------------------------------------------------------------------------------------------- */
public boolean unwrapBlockDelimiters(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Convert the generic parameter types to XString
------------------------------------------------------------------------------------------ */
XString startDelimiter = new XString(pArguments[0]);
XString endDelimiter = new XString(pArguments[1]);
/*.
==========================================================================================
This variable will be returned. It indicates whether or not this pass through the file
found any block delimiters that needed to be unwrapped. This method can only find one
instance of a wrapped delimiter per line on each pass through the file. If there are
multiple instances on single lines, they can only be resolved by calling this method
repeatedly until they are all resolved. If this method returns true, it means that a
delimiter that had to be unwrapped was found and that another pass needs to be made
through the file to see if there are any more on the lines on which one was found and
resolved. When this method returns false, it means all instances of wrapped delimeters on
all lines have been resolved.
------------------------------------------------------------------------------------------ */
boolean wrappedDelimiterFound = false;
/*.
==========================================================================================
For each line of the file, ...
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
/*.
==========================================================================================
Get the next line from the file, its whitespace prefix and a trimmed version of it.
------------------------------------------------------------------------------------------ */
XString currentLine = pIter.next().trimRight();
XString currentLineIndent = currentLine.whitespacePrefix();
XString currentLineTrimmed = currentLine.trim();
/*.
==========================================================================================
If there's a start delimiter that got wrapped onto the end of a line of other text, output
the other text as its own line and then output a start delimiter on the next line by
itself
------------------------------------------------------------------------------------------ */
if (currentLineTrimmed.endsWithIgnoreCase(startDelimiter) && ( ! currentLineTrimmed.equalsIgnoreCase(startDelimiter)))
{
currentLine = currentLine.trimRightIgnoreCase(startDelimiter);
pOutput.println(currentLine);
pOutput.println(currentLineIndent.concat(startDelimiter));
wrappedDelimiterFound = true;
}
/*.
==========================================================================================
If there's an end delimiter that got wrapped onto the start of a line of other text,
output an end delimiter on the next line by itself and then output the other text as its
own line
------------------------------------------------------------------------------------------ */
else if (currentLineTrimmed.startsWithIgnoreCase(endDelimiter) && ( ! currentLineTrimmed.equalsIgnoreCase(endDelimiter)))
{
currentLine = currentLine.trimLeftIgnoreCase(currentLineIndent.concat(endDelimiter));
pOutput.println(currentLineIndent.concat(endDelimiter));
pOutput.println(currentLineIndent.concat(currentLine));
wrappedDelimiterFound = true;
}
/*.
==========================================================================================
If there's an end delimiter that got wrapped onto the end of a line of other text, output
the other text as its own line and then output an end delimiter on the next line by itself
------------------------------------------------------------------------------------------ */
else if (currentLineTrimmed.endsWithIgnoreCase(endDelimiter) && ( ! currentLineTrimmed.equalsIgnoreCase(endDelimiter)))
{
currentLine = currentLine.trimRightIgnoreCase(endDelimiter);
pOutput.println(currentLine);
pOutput.println(currentLineIndent.concat(endDelimiter));
wrappedDelimiterFound = true;
}
/*.
==========================================================================================
If there's a start delimiter that got wrapped onto the start of a line of other text,
output a start delimiter on the next line by itself and then output the other text as its
own line
------------------------------------------------------------------------------------------ */
else if (currentLineTrimmed.startsWithIgnoreCase(startDelimiter) && ( ! currentLineTrimmed.equalsIgnoreCase(startDelimiter)))
{
currentLine = currentLine.trimLeftIgnoreCase(currentLineIndent.concat(startDelimiter));
pOutput.println(currentLineIndent.concat(startDelimiter));
pOutput.println(currentLineIndent.concat(currentLine));
wrappedDelimiterFound = true;
}
/*.
==========================================================================================
If this is just a normal line without any stasrt or end delimiter at its beginning or end,
then just output it as is
------------------------------------------------------------------------------------------ */
else
{
pOutput.println(currentLine);
}
}
return wrappedDelimiterFound;
}
/*: :METHOD:078:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method indents all of the delimited block's content where the delimited block is delimited by
the specified start and end delimiters.
<P><B>Implementation: </B><A HREF="TextFile.java.html#078">View source</A>
@param
pStartDelimiter is the XString that demarcates the start of the block of text to indent.
@param
pEndDelimiter is the XString that demarcates the end of the block of text to indent.
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1, Type2> void indentDelimitedBlockContentFromDelimiters(Type1 pStartDelimiter, Type2 pEndDelimiter) throws Exception
{
this.modify("indentDelimitedBlockContentFromDelimiters", pStartDelimiter, pEndDelimiter);
}
/*: :METHOD:079:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method indents all of the delimited block's content where the delimited block is delimited by
the specified start and end delimiters.
<P><B>Implementation: </B><A HREF="TextFile.java.html#079">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments. It is where pStartDelimiter and pEndDelimiter
are placed.
*//*
---------------------------------------------------------------------------------------------------- */
public void indentDelimitedBlockContentFromDelimiters(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Convert the generic parameter types to XString
------------------------------------------------------------------------------------------ */
XString startDelimiter = new XString(pArguments[0]);
XString endDelimiter = new XString(pArguments[1]);
/*.
==========================================================================================
For each line of the file, if it is a start delimiter, call out to output it, indent its
subordinate lines, and output its matching end delimiter. Otherwise, just send it to
output.
------------------------------------------------------------------------------------------ */
while (pIter.hasNext())
{
/*.
==========================================================================================
Get the next line from the file and a trimmed version of it.
------------------------------------------------------------------------------------------ */
XString currentLine = pIter.next();
XString currentTrimmed = currentLine.trim();
/*.
==========================================================================================
If this line is a start delimiter, indent it, everything subordinate to it, and its
matching end delimiter.
------------------------------------------------------------------------------------------ */
if (currentTrimmed.equals(startDelimiter))
{
this.indentDelimitedBlockContentFromDelimiters(pIter, pOutput, startDelimiter, endDelimiter, currentLine);
}
/*.
==========================================================================================
Otherwise, it's just a normal line so send it to the output unchanged
------------------------------------------------------------------------------------------ */
else
{
pOutput.println(currentLine);
}
}
}
/*: :METHOD:080:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method is the recursive portion of the method that indents all of the delimited block's content
where the delimited block is delimited by the specified start and end delimiters.
<P><B>Implementation: </B><A HREF="TextFile.java.html#080">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pStartDelimiter is the XString that demarcates the start of the block of text to indent.
@param
pEndDelimiter is the XString that demarcates the end of the block of text to indent.
@param
pCurrentLine is the current line from the input file and it is expected to consist of a start
delimiter.
*//*
---------------------------------------------------------------------------------------------------- */
public void indentDelimitedBlockContentFromDelimiters(XStringsIterator pIter, TextWriter pOutput, XString pStartDelimiter, XString pEndDelimiter, XString pCurrentLine) throws Exception
{
/*.
==========================================================================================
This is how far in the delimited block content should be indented from the start
delimiter.
------------------------------------------------------------------------------------------ */
XString oneIndent = new XString(" ");
/*.
==========================================================================================
This is the extra indentation characters that will be prepended to every line in the
delimited block to insure that each is indented the right amount from the prior non-blank
line of text
------------------------------------------------------------------------------------------ */
XString extraIndent = new XString("");
/*.
==========================================================================================
When we arrive in this method, a start delimiter has been found on the current line and
that current line was passed into this method without being output. Now set all the local
line variables to represent this incomming start delimiter line.
------------------------------------------------------------------------------------------ */
XString currentLine = pCurrentLine;
XString currentLineIndent = currentLine.whitespacePrefix();
XString currentLineTrimmed = currentLine.trim();
/*.
==========================================================================================
And since it's the start delimiter line, just write it out.
------------------------------------------------------------------------------------------ */
pOutput.println(currentLine);
/*.
==========================================================================================
Remember how far in the start delimiter was indented
------------------------------------------------------------------------------------------ */
XString startDelimiterIndent = currentLineIndent;
/*.
==========================================================================================
Now we just start reading each suceeding line. The first one determines if the content
needs to be indented more than it already is.
------------------------------------------------------------------------------------------ */
boolean firstContentLine = true;
boolean endFound = false;
while (pIter.hasNext())
{
/*.
==========================================================================================
Get the next line from the file, its whatespace prefix and a trimmed version of it.
------------------------------------------------------------------------------------------ */
currentLine = pIter.next();
currentLineIndent = currentLine.whitespacePrefix();
currentLineTrimmed = currentLine.trim();
/*.
==========================================================================================
If this is the first non-blank line of content, then this is where we figure out if we
need to indent the content and if so, by how much.
------------------------------------------------------------------------------------------ */
if (firstContentLine && (! currentLineTrimmed.isEmpty()))
{
firstContentLine = false;
/*.
==========================================================================================
If it is not indented more than the start delimiter is indented, then figure out how much
additional indent is needed to be one indent level further in than the start delimiter and
change extraIndent to be of that length of space characters.
------------------------------------------------------------------------------------------ */
if (currentLineIndent.length() < startDelimiterIndent.length() + oneIndent.length())
{
int amountOfExtraIndent = startDelimiterIndent.length() + oneIndent.length() - currentLineIndent.length();
extraIndent = XString.fill(amountOfExtraIndent, ' ');
}
}
/*.
==========================================================================================
THIS BLOCK IS THE ONLY NORMAL WAY OUT OF THIS METHOD.
Since we came into this method because a start delimiter was found, the only legitimate
way out of the methhod is here - when a matching end delimiter is found. Output it with
the proper indentation to line up with the start delimiter
------------------------------------------------------------------------------------------ */
endFound = currentLineTrimmed.equals(pEndDelimiter);
if (endFound)
{
/*.
==========================================================================================
Output the currentLine with the same indent as its corresonding start delimiter
------------------------------------------------------------------------------------------ */
currentLine = startDelimiterIndent.concat(pEndDelimiter);
pOutput.println(currentLine);
/*.
==========================================================================================
And return
------------------------------------------------------------------------------------------ */
return;
}
/*.
==========================================================================================
Otherwise, if we run into another start delimiter before we find the matching end
delimiter for the start delimiter that was passed into this method, it means we have
encountered a nested start delimiter. Pass it into a recursive call to this method for
processing.
------------------------------------------------------------------------------------------ */
else if (currentLineTrimmed.equals(pStartDelimiter))
{
this.indentDelimitedBlockContentFromDelimiters(pIter, pOutput, pStartDelimiter, pEndDelimiter, extraIndent.concat(currentLine));
}
/*.
==========================================================================================
Otherwise, prepend the current extra indentation to the current line and send it to
output.
------------------------------------------------------------------------------------------ */
else
{
currentLine = extraIndent.concat(currentLine);
pOutput.println(currentLine);
}
}
/*.
==========================================================================================
If we get here, we got to the end of file and the start/end delimiters didn't all match up
so throw an exception
------------------------------------------------------------------------------------------ */
throw new Exception("TextFile.indentDelimitedBlockContentFromDelimiters(): " + pStartDelimiter + " delimiter is unmatched");
}
/*: :METHOD:081:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method modifies this TextFile in place to have no more and no less than the specified number of
consecutive empty lines at the end of this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#081">View source</A>
@param
pNumberOfEmptyLines is the exact number of empty lines that will be found in the sequence of
consecutive empty lines at the end of this TextFile after it has been modified in place.
*//*
---------------------------------------------------------------------------------------------------- */
public void setEmptyLinesAtEof(long pNumberOfEmptyLines) throws Exception
{
this.modify("setEmptyLinesAtEof", pNumberOfEmptyLines);
}
/*: :METHOD:082:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method modifies a file in place to have no more and no less than the specified number of
consecutive empty lines at the end of the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#082">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain
pNumberOfEmptyLines as the first element of the list
*//*
---------------------------------------------------------------------------------------------------- */
public void setEmptyLinesAtEof(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
long numberOfEmptyLines = (long)pArguments[0];
/*.
==========================================================================================
Read each line of the source file, count any sequences of consecutive empty lines and for
the sequence at the end of the file, replace the sequence with the specified number of
empty lines.
------------------------------------------------------------------------------------------ */
XString trimmedLine = null;
XString line = null;
long count = 0;
while (pIter.hasNext())
{
line = pIter.next();
trimmedLine = line.trim();
if (trimmedLine.isEmpty())
{
count++;
}
else
{
while (count > 0)
{
count--;
pOutput.println();
}
pOutput.println(line);
}
}
/*.
==========================================================================================
When the EOF is encountered, we end up here without having output the current sequence of
empty lines. Output the specified number of empty lines now.
------------------------------------------------------------------------------------------ */
while (numberOfEmptyLines-- > 0) pOutput.println();
}
/*: :METHOD:083:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method modifies this TextFile in place to have no more than the specified number of consecutive
empty lines in any sequence of empty lines in this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#083">View source</A>
@param
pNumberOfEmptyLines is the maximum number of empty lines that will be found in any sequence of
consecutive empty lines in this TextFile after it has been modified in place.
*//*
---------------------------------------------------------------------------------------------------- */
public void setMaxConsecutiveEmptyLines(long pNumberOfEmptyLines) throws Exception
{
this.modify("setMaxConsecutiveEmptyLines", pNumberOfEmptyLines);
}
/*: :METHOD:084:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method modifies a file in place to have no more than the specified number of consecutive empty
lines in any sequence of empty lines in the file.
<P><B>Implementation: </B><A HREF="TextFile.java.html#084">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain
pNumberOfEmptyLines as the first element of the list
*//*
---------------------------------------------------------------------------------------------------- */
public void setMaxConsecutiveEmptyLines(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
long numberOfEmptyLines = (long)pArguments[0];
/*.
==========================================================================================
Read each line of the source file, count any sequences of consecutive empty lines and
replace each sequence with itself or with the specified number of empty lines, whichever
is fewer.
------------------------------------------------------------------------------------------ */
XString trimmedLine = null;
XString line = null;
long count = 0;
while (pIter.hasNext())
{
line = pIter.next();
trimmedLine = line.trim();
if (trimmedLine.isEmpty())
{
count = UMath.min(numberOfEmptyLines, count + 1);
}
else
{
while (count > 0)
{
count--;
pOutput.println();
}
pOutput.println(line);
}
}
/*.
==========================================================================================
When the EOF is encountered, we end up here without having output the current sequence of
empty lines. Output this last sequence now.
------------------------------------------------------------------------------------------ */
while (count-- > 0) pOutput.println();
}
/*: :METHOD:085:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method modifies this TextFile in place to have its content put into columns. The lines in the
file are counted and divided by the number of columns. The result is the number of lines it puts
into each column. Each line is taken in full as one string and placed into one of the columns. The
columns are vertically aligned and seperated by one space.
<P><B>Implementation: </B><A HREF="TextFile.java.html#085">View source</A>
@param
pColumns is the number of columns to put the content of the file into
*//*
---------------------------------------------------------------------------------------------------- */
public void columnize(int pColumns) throws Exception
{
this.columnize(pColumns, " ");
}
/*: :METHOD:086:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method modifies this TextFile in place to have its content put into columns. The lines in the
file are counted and divided by the number of columns. The result is the number of lines it puts
into each column. Each line is taken in full as one string and placed into one of the columns. The
columns are vertically aligned and seperated by the spacer string.
<P><B>Implementation: </B><A HREF="TextFile.java.html#086">View source</A>
@param
pColumns is the number of columns to put the content of the file into
@param
pSpacer is the string to seperate the columns with
*//*
---------------------------------------------------------------------------------------------------- */
public <Type1> void columnize(int pColumns, Type1 pSpacer) throws Exception
{
this.modify("columnize", pColumns, XString.toXString(pSpacer));
}
/*: :METHOD:087:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method modifies this TextFile in place to have its content put into columns. The lines in the
file are counted and divided by the number of columns. The result is the number of lines it puts
into each column. Each line is taken in full as one string and placed into one of the columns. The
columns are vertically aligned and seperated by the spacer string.
<P><B>Implementation: </B><A HREF="TextFile.java.html#087">View source</A>
@param
pIter is an XStringsIterator for reading this TextFile
@param
pOutput is a TextWriter for writing the modified content of this TextFile to the output file.
@param
pArguments is a variable sized list of arguments and this method expects it to contain:
<BLOCKQUOTE>
pArguments[0]: int colCount
<BLOCKQUOTE>
Is the number of columns to put the content of the file into
</BLOCKQUOTE>
pArguments[1]: XString spacer
<BLOCKQUOTE>
Is the string to seperate the columns with
</BLOCKQUOTE>
</BLOCKQUOTE>
*//*
---------------------------------------------------------------------------------------------------- */
public void columnize(XStringsIterator pIter, TextWriter pOutput, Object... pArguments) throws Exception
{
/*.
==========================================================================================
Get the arguments
------------------------------------------------------------------------------------------ */
int colCount = (int)pArguments[0];
XString spacer = new XString(pArguments[1]);
/*.
==========================================================================================
each line of the file will be stored as an element in an ArrayList. read and store each
line of the file
------------------------------------------------------------------------------------------ */
ArrayList<XString> lines = new ArrayList<XString>();
while (pIter.hasNext())
{
lines.add(pIter.next());
}
/*.
==========================================================================================
figure out how many rows to put in each column
------------------------------------------------------------------------------------------ */
int rowCount = lines.size() / colCount;
int rowExcess = lines.size() % colCount;
/*.
==========================================================================================
feed the lines into columns
------------------------------------------------------------------------------------------ */
ArrayList<ArrayList<XString>> columns = new ArrayList<ArrayList<XString>>();
XStringsIterator lineIter = new XStringsIterator(lines);
for (int colIdx=0; colIdx<colCount; colIdx++)
{
if (!lineIter.hasNext()) break;
ArrayList<XString> col = new ArrayList<XString>();
columns.add(col);
int maxRowIdx = rowCount + ((--rowExcess >= 0)? 1 : 0);
for (int rowIdx=0; rowIdx<maxRowIdx; rowIdx++)
{
if (!lineIter.hasNext()) break;
col.add(lineIter.next());
}
}
lines = null;
/*.
==========================================================================================
figure out the max width of each column and pad each string in the column to that max
width
------------------------------------------------------------------------------------------ */
for (int colIdx=0; colIdx<colCount; colIdx++)
{
ArrayList<XString> col = columns.get(colIdx);
int max = 0;
for (XString str : col)
{
max = UMath.max(max, str.length());
}
for (int rowIdx=0; rowIdx<col.size(); rowIdx++)
{
col.set(rowIdx, col.get(rowIdx).alignLeft(max, ' '));
}
}
/*.
==========================================================================================
write out the columns to the file
------------------------------------------------------------------------------------------ */
for (int rowIdx=0; rowIdx<columns.get(0).size(); rowIdx++)
{
for (int colIdx=0; colIdx<colCount; colIdx++)
{
ArrayList<XString> col = columns.get(colIdx);
if (rowIdx < col.size())
{
XString str = col.get(rowIdx);
if (colIdx > 0)
{
pOutput.print(spacer);
}
pOutput.print(str);
}
}
pOutput.println();
}
}
/*: :METHOD:088:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This method sets the ConsoleStream for this object.
<P><B>Implementation: </B><A HREF="TextFile.java.html#088">View source</A>
@return
A reference to this object
@param
pConsole is a ConsoleStream through which this objects sends its output.
*//*
---------------------------------------------------------------------------------------------------- */
public TextFile setOut(ConsoleStream pConsole)
{
cOut = pConsole;
return this;
}
/*: :METHOD:089: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="TextFile.java.html#089">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public TextFile test() throws Exception
{
cOut.titledPrintf
(
"\"HELLO WORLD!\"",
"%s %s %s",
"I'm an object of the", CLASS_NAME, "class, and I approved this message."
);
this.testFixHtmlElementIndentation();
return this;
}
/*: :METHOD:090:BOOKMARK:
====================================================================================================
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
==================================================================================================== *//**
This is a test method that formats certain HTML elements if they are found in this TextFile.
<P><B>Implementation: </B><A HREF="TextFile.java.html#090">View source</A>
*//*
---------------------------------------------------------------------------------------------------- */
public void testFixHtmlElementIndentation() throws Exception
{
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<BLOCKQUOTE>", "</BLOCKQUOTE>");
this.indentDelimitedBlockFromPriorText("<BLOCKQUOTE>", "</BLOCKQUOTE>");
this.indentDelimitedBlockContentFromDelimiters("<BLOCKQUOTE>", "</BLOCKQUOTE>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<PRE>", "</PRE>");
this.indentDelimitedBlockFromPriorText("<PRE>", "</PRE>");
this.indentDelimitedBlockContentFromDelimiters("<PRE>", "</PRE>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<PRE id=\"unindent\">", "</PRE>");
this.indentDelimitedBlockFromPriorText("<PRE id=\"unindent\">", "</PRE>");
this.indentDelimitedBlockContentFromDelimiters("<PRE id=\"unindent\">", "</PRE>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<DL>", "</DL>");
this.indentDelimitedBlockFromPriorText("<DL>", "</DL>");
this.indentDelimitedBlockContentFromDelimiters("<DL>", "</DL>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<DT>", "</DT>");
this.indentDelimitedBlockFromPriorText("<DT>", "</DT>");
this.indentDelimitedBlockContentFromDelimiters("<DT>", "</DT>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<DD>", "</DD>");
this.indentDelimitedBlockContentFromDelimiters("<DD>", "</DD>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<B>", "</B>");
this.indentDelimitedBlockFromPriorText("<B>", "</B>");
this.indentDelimitedBlockContentFromDelimiters("<B>", "</B>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
this.unwrapBlockDelimiters("<A href=\"mailto:sourcecode.v01@cosmicabyss.com\">", "</A>");
this.indentDelimitedBlockFromPriorText("<A href=\"mailto:sourcecode.v01@cosmicabyss.com\">", "</A>");
this.indentDelimitedBlockContentFromDelimiters("<A href=\"mailto:sourcecode.v01@cosmicabyss.com\">", "</A>");
/*.
==========================================================================================
------------------------------------------------------------------------------------------ */
String thisFileName = this.getName();
String sourceLink = "<A href=\"" + thisFileName + ".html\">";
this.unwrapBlockDelimiters(sourceLink, "</A>");
this.indentDelimitedBlockFromPriorText(sourceLink, "</A>");
this.indentDelimitedBlockContentFromDelimiters(sourceLink, "</A>");
}
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ 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(TextFile.class.getName());
private static final int DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();
/*.
==========================================================================================
This classes's constants
------------------------------------------------------------------------------------------ */
private static int sTabSize = 3;
private static XString sDelimiters = new XString(" ");
private static XString sSeparator = new XString(" ");
/*.
==========================================================================================
Class variables
cOut : console output.
------------------------------------------------------------------------------------------ */
private static ConsoleStream cOut = ConsoleStream.getSingleton();
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Inner Classes ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Public Static Methods ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */
/*: :METHOD:091: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.TextFile
</DD>
</DT>
</DL>
<P><B>Implementation: </B><A HREF="TextFile.java.html#091">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 a TextFile to play with
------------------------------------------------------------------------------------------ */
TextFile tf = new TextFile(pArgs[0]);
tf.test();
}
} // class TextFile
/*:.
==============================================================================================================
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[ Notes ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
============================================================================================================== */