/*::.
==================================================================================================================================
=================================================¦ Copyright © 2009 Allen Baker ¦=================================================
                                                 +------------------------------+
File:       CsvFile.java
Originator: Allen Baker (2009.03.02 11:34)
LayoutRev:  5
================================================================================================================================== */



/*.
==========================================================================================
Package
------------------------------------------------------------------------------------------ */
package cosmicabyss.com.lib;



/*.
==========================================================================================
Imports
------------------------------------------------------------------------------------------ */
import java.io.*;
import java.util.*;
import java.net.*;



/*::
======================================================================================================================== *//**
This class represents and understands CsvFiles. It provides fields and methods for accessing and interpreting the
content of these files. It assumes the first line of the file contains column headers for every column in the file. The
content of the header line is fundamental to the way this class interprets the content of the CSV file. It determines
how many columns this class expects to find in all subsequent rows. Furthermore, the actual strings used as column
headers in the first row of the file are used to determine which column IDs this class assigns to the columns.

<P>
   <DL>
      <DT>
         <B>
            Example usage:
         </B>
         <DD>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  no example provided
               </PRE>
            </BLOCKQUOTE>
         </DD>
      </DT>
      <DT>
         <B>
            View Source:
         </B>
         <DD>
            <A href="CsvFile.java.html">
               CsvFile.java
            </A>
         </DD>
      </DT>
      <DT>
         <B>
            Author:
         </B>
         <DD>
            <A href="mailto:sourcecode.v01@cosmicabyss.com">
               Allen Baker
            </A>
         </DD>
      </DT>
   </DL>
*//*
======================================================================================================================== */
public class CsvFile extends DelimitedFile
   {



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Public Constants And Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Class Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Class Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Instance Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Instance Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Protected Constants And Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Class Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Class Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Instance Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Instance Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Private Constants And Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  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(CsvFile.class.getName());
   private static final int      DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Class Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*.
   ==========================================================================================
   cOut : console output.
   ------------------------------------------------------------------------------------------ */
   private static ConsoleStream  cOut = ConsoleStream.getSingleton();



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Instance Constants  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Instance Variables  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*.
   ==========================================================================================
   The csv column definitions from a csv column definition file.
   ------------------------------------------------------------------------------------------ */
   private CsvFileColDefs  iColDefs = null;
   public  CsvFileColDefs  colDefs() { return iColDefs; }
   /*.
   ==========================================================================================
   Map of column ids to the standardized column header strings
   ------------------------------------------------------------------------------------------ */
   private HashMap<Integer,XString>  iColIdStandardHdrStrMap    = new HashMap<Integer,XString>();
   private boolean                   iColIdStandardHdrStrMapSet = false;
   /*.
   ==========================================================================================
   Map of column ids to commonly encountered column header strings. The typical header
   strings map will include the standard header strings because they are commonly encountered
   too.
   ------------------------------------------------------------------------------------------ */
   private HashMap<Integer,Set<XString>>  iColIdTypicalHdrStrMap    = new HashMap<Integer,Set<XString>>();
   private boolean                        iColIdTypicalHdrStrMapSet = false;
   /*.
   ==========================================================================================
   The actual column numbers in this csv file that map to the column ids (array index) these
   variables are set so that the algorithm for mapping a column id to an actual column number
   in the file only has to run one time. The result is stored in these variables for reuse. A
   -1 value for any of these means that an actual column for that column id was not found in
   this csv file. The actual column matching a column id is found by looking at the column
   header strings and when one is found that is associated with the column id, that column
   number is then mapped to the column id.
   ------------------------------------------------------------------------------------------ */
   private int[]  iColNums = null;
   /*.
   ==========================================================================================
   iLineNum:
      Keeps track of the last line number of the file that was Read. The first line of the
      file is line 1.
   iLastLine:
      Keeps a copy of the last line of the file that was read. This copy of the last line
      read is mutable - its column values can be changed by using the set*() methods.
   ------------------------------------------------------------------------------------------ */
   private int                 iLineNum  = 0;
   private ArrayList<XString>  iLastLine = null;



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Inner Classes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Inner Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Inner Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Inner Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Private Class Initialization  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   static
      {
      /*.
      ==========================================================================================
      Make sure all the class constants and variables are initialized the first time the JVM
      loads this class code and before anything else in this class is accessed
      ------------------------------------------------------------------------------------------ */
      initializeClassConstantsAndVariables();
      }



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Private Methods  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Instance Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes all the instance constants and variables

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#000">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private <Type> boolean initializeInstanceConstantsAndVariables(Type pColDefsFile) throws Exception
      {
      boolean  successCode = true;

      iColDefs = new CsvFileColDefs(pColDefsFile);

      initializeColIdStandardHdrStrMap();
      initializeColIdTypicalHdrStrMap();
      initializeColNums();

      return successCode;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes the map of colIds to standard column header strings

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#001">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private void initializeColIdStandardHdrStrMap() throws Exception
      {
      /*.
      ==========================================================================================
      Only go through this initialization one time - the first time it is called
      ------------------------------------------------------------------------------------------ */
      if (!iColIdStandardHdrStrMapSet)
         {
         iColIdStandardHdrStrMapSet = true;
         for (int colId=0; colId<iColDefs.numCols(); colId++)
            {
            addColIdStandardHdrStr(colId,iColDefs.stringName(colId));
            }
         }
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes the map of colIds to typical column header strings. The typical header
   strings map includes the standard header strings.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#002">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private void initializeColIdTypicalHdrStrMap() throws Exception
      {
      /*.
      ==========================================================================================
      Only go through this initialization one time - the first time it is called
      ------------------------------------------------------------------------------------------ */
      if (!iColIdTypicalHdrStrMapSet)
         {
         iColIdTypicalHdrStrMapSet = true;
         /*.
         ==========================================================================================
         Include the Standard Headers in the map because they are commonly encountered too then add
         the aliases
         ------------------------------------------------------------------------------------------ */
         for (int colId=0; colId<iColDefs.numCols(); colId++)
            {
            /*.
            ==========================================================================================
            The standard header for this column id
            ------------------------------------------------------------------------------------------ */
            addColIdTypicalHdrStr(colId,iColDefs.stringName(colId));
            /*.
            ==========================================================================================
            All the various aliases for this column id.
            ------------------------------------------------------------------------------------------ */
            for (int aliasNum=0; aliasNum<7; aliasNum++)
               {
               XString  alias = iColDefs.alias(colId,aliasNum);
               if (alias != null)
                  {
                  addColIdTypicalHdrStr(colId,alias);
                  }
               }
            }
         }
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds a colId / headerString pair to the standard colId-to-header string map

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#003">View source</A>

   @param
      pColId is the column id to add to the map
   @param
      pHeaderString is the header string to map to the column id in the map
   *//*
   ---------------------------------------------------------------------------------------------------- */
   private <Type> void addColIdStandardHdrStr(int pColId, Type pHeaderString)
      {
      iColIdStandardHdrStrMap.put(pColId,new XString(pHeaderString));
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method adds a colId / headerString pair to the colId-to-header string map

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#004">View source</A>

   @param
      pColId is the column id to add to the map
   @param
      pHeaderString is the header string to map to the column id in the map
   *//*
   ---------------------------------------------------------------------------------------------------- */
   private <Type> void addColIdTypicalHdrStr(int pColId, Type pHeaderString)
      {
      /*.
      ==========================================================================================
      ------------------------------------------------------------------------------------------ */
      Set<XString>  headerStrings = iColIdTypicalHdrStrMap.get(pColId);
      /*.
      ==========================================================================================
      ------------------------------------------------------------------------------------------ */
      if (headerStrings == null)
         {
         headerStrings = new HashSet<XString>();
         iColIdTypicalHdrStrMap.put(pColId,headerStrings);
         }
      /*.
      ==========================================================================================
      ------------------------------------------------------------------------------------------ */
      headerStrings.add(new XString(pHeaderString));
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes the instance variables that keep track of which column numbers are
   associated with which fields.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#005">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private void initializeColNums()
      {
      iColNums = new int[iColDefs.numCols()];
      for (int i=0; i<iColDefs.numCols(); i++)
         {
         iColNums[i] = colSearch(i,false);
         }
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method gets a column number for a column id and optionally prints an error message to cOut if
   it cannot find a column number for the column id.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#006">View source</A>

   @return
      The column number in this file that corresponds to the given colId or -1 if a corresponding colum
      is not found

   @param
      pColId is the column id for which the corresponding column number in this file is returned.
   @param
      pShowError tells this method whether or not to print an error message if it cannot find a column
      number in this file that corresponds to the column id
   *//*
   ---------------------------------------------------------------------------------------------------- */
   private int colSearch(int pColId, boolean pShowError)
      {
      /*.
      ==========================================================================================
      Search the typical header strings first. Get all the values that go with this key
      ------------------------------------------------------------------------------------------ */
      Set<XString>  typicalHdrStrs = iColIdTypicalHdrStrMap.get(pColId);
      if (typicalHdrStrs != null)
         {
         /*.
         ==========================================================================================
         For each value check if there is a column in the DelimitedFile with a header that matches
         the value and if so, then return its column number
         ------------------------------------------------------------------------------------------ */
         for (XString hStr : typicalHdrStrs)
            {
            int  colNum = super.colNumIgnoreCase(hStr);
            if (colNum != (-1))
               {
               return colNum;
               }
            }
         }
      /*.
      ==========================================================================================
      If a match wasnt found return -1
      ------------------------------------------------------------------------------------------ */
      try
         {
         if (pShowError) cOut.printfWithSeverity(Const.WARNING,"Not found -- CsvFile.col(%02d) for %s\n",pColId,stdHdr(pColId));
         }
      catch (Exception e)
         {
         }
      return (-1);
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Private Class Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method initializes all the class constants and variables

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#007">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   private static void initializeClassConstantsAndVariables()
      {
      }



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Protected Methods  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Instance Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Protected Class Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Public Methods  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#008">View source</A>

   @param
      xFile is an XFile that this object will process as an CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type> CsvFile(XFile xfile, Type pColDefsFile) throws Exception
      {
      super(xfile.getCanonicalPath());
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#009">View source</A>

   @param
      tFile is an TextFile that this object will process as an CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type> CsvFile(TextFile tfile, Type pColDefsFile) throws Exception
      {
      super(tfile.getCanonicalPath());
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#010">View source</A>

   @param
      xFile is an CsvFile that this object will process as an CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type> CsvFile(CsvFile tfile, Type pColDefsFile) throws Exception
      {
      super(tfile.getCanonicalPath());
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#011">View source</A>

   @param
      Uri is a URI that this object will process as an CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type> CsvFile(URI uri, Type pColDefsFile) throws Exception
      {
      super(uri);
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#012">View source</A>

   @param
      File is an File that this object will process as an CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type> CsvFile(File file, Type pColDefsFile) throws Exception
      {
      super(file.getCanonicalPath());
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#013">View source</A>

   @param
      Parent is a File that this object will combine with child and process as an CsvFile
   @param
      Child is a child pathname string that this object will combine with parent and process as an
      CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2> CsvFile(File parent, Type1 child, Type2 pColDefsFile) throws Exception
      {
      super(parent,child);
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#014">View source</A>

   @param
      Pathname is a pathname string that this object will process as an CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2> CsvFile(Type1 pathname, Type2 pColDefsFile) throws Exception
      {
      super(pathname);
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method creates an instance of the CsvFile class.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#015">View source</A>

   @param
      Parent is a pathname string that this object will combine with child and process as an CsvFile
   @param
      Child is a child pathname string that this object will combine with parent and process as an
      CsvFile
   @param
      pColDefsFile identifies the file containing the csv column definitions to use for interpreting
      this csv file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public <Type1,Type2,Type3> CsvFile(Type1 parent, Type2 child, Type3 pColDefsFile) throws Exception
      {
      super(parent,child);
      initializeInstanceConstantsAndVariables(pColDefsFile);
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Instance Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method is an accessor that gets the value of the instance data: lineNum - the line number of
   the most recent line read from the file. The first line number in the file is 1.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#016">View source</A>

   @return
      The value of the instance data.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public int lineNum()
      {
      return iLineNum;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method is an mutator that sets a value in the most recently read line. The field set is the one
   identified by the column id.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#017">View source</A>

   @return
      The previous value of the instance data

   @param
      pNewVal is the new value to set the intance data to
   @param
      pColId is the column id for which the corresponding column value of the most recently read line
      is set.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public XString set(int pColId, XString pNewVal)
      {
      return iLastLine.set(col(pColId),pNewVal);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method is an accessor that gets the value in the most recently read line from the column
   (field) identified by a column id.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#018">View source</A>

   @return
      The value of the field. If the column corresponding to the column id is not found then this
      method returns the empty string.

   @param
      pColId is the column id for which the corresponding column value of the most recently read line
      is returned.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public XString val(int pColId)
      {
      int  col = col(pColId);
      /*.
      ==========================================================================================
      If the col id does not have a corresponding column in the file, return the empty string,
      otherwise, return the value of the field
      ------------------------------------------------------------------------------------------ */
      return ((col == (-1))? XString.EMPTY : iLastLine.get(col));
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method gets a column number for a column id. If it cannot find a column number for the column
   id.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#019">View source</A>

   @return
      The column number in this file that corresponds to the given colId or -1 if a corresponding colum
      is not found

   @param
      pColId is the column id for which the corresponding column number in this file is returned.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public int col(int pColId)
      {
      return iColNums[pColId];
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method gets the standard header string that is associated with a specified column id

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#020">View source</A>

   @return
      And XString containing the stasndard header string for the column that is identified by the
      column id

   @param
      pColId identifies the column for which the standard header string is returned.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public XString stdHdr(int pColId)
      {
      return iColIdStandardHdrStrMap.get(pColId);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns the most recent line read from the delimited file in an already tokenized form.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#021">View source</A>

   @return
      An ArrayList in which each element is the next sequential token from the current line of the
      delimited file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public ArrayList<XString> currLine()
      {
      return iLastLine;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#022">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void println() throws Exception
      {
      /*.
      ==========================================================================================
      Find the longest standard column header string
      ------------------------------------------------------------------------------------------ */
      int  maxLen = 0;
      for (int i=0; i<iColDefs.numCols(); i++)
         {
         maxLen = UMath.max(maxLen,iColDefs.stringName(i).length());
         }
      /*.
      ==========================================================================================
      Now print out each standard column header string and the value of that column in the
      current row of the csv file.
      ------------------------------------------------------------------------------------------ */
      cOut.println();
      for (int i=0; i<iColDefs.numCols(); i++)
         {
         XString  line = iColDefs.stringName(i).alignLeft(maxLen+1,'-').concat(": ").concat(val(i));
         cOut.println(line);
         }
      cOut.println();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method reads the next line of the delimited file. It is really just a simplified way of calling
   parsedCsvLine() because it does not return the newly read line. Instead, the calling program would
   use the currLine() method to retrieve the newly read line. Alternatively, the calling program can
   use the field accessor methods (like valCi(), valAssetAlias(), ...) to get the actual column values
   from the newly read line.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#023">View source</A>

   *//*
   ---------------------------------------------------------------------------------------------------- */
   public void readNext() throws Exception
      {
      parsedCsvLine();
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method returns the next line of the delimited file in an already tokenized form.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#024">View source</A>

   @return
      An ArrayList in which each element is the next sequential token from the current line of the
      delimited file.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public ArrayList<XString> parsedCsvLine() throws Exception
      {
      /*.
      ==========================================================================================
      Get the current line from the file. Every time a line is read, the line counter is
      incremented
      ------------------------------------------------------------------------------------------ */
      iLastLine = super.parsedLine();
      iLineNum++;
      /*.
      ==========================================================================================
      If it's a broken line, try to repair it. Broken lines happen when a field contains a
      newline character.
      ------------------------------------------------------------------------------------------ */
      while ((iLastLine.size() < super.numCols()) && (super.hasNext()))
         {
         /*.
         ==========================================================================================
         Tell 'em it's a broken line, which line it is, and that it is going to be spliced to the
         next line in the file if there is one.
         ------------------------------------------------------------------------------------------ */
         cOut.printf("      " + super.getName() + ") Line %d is short; splicing to line %d\n",iLineNum,iLineNum+1);
         /*.
         ==========================================================================================
         The working assumption when a line with too few tokens is found is that it is a broken
         line - a line in which a token contains an embedded newline. The token with the embedded
         newline will look like the last token in this line. In fact, if the assumption is right,
         the last token in the current line (which had an embedded newline) is only part of the
         token. The rest of the token shows up as the first token of the next line. Splicing the
         current line with the next line involves concatenating the last token of the current line
         with the first token of the next line and treating the combined list of the current line's
         and the next line's tokens as one line.
         ------------------------------------------------------------------------------------------ */
         int      lastItem   = iLastLine.size() - 1;
         XString  lastToken  = (lastItem >= 0)? iLastLine.remove(lastItem) : XString.EMPTY;
         /*.
         ==========================================================================================
         Get the next line from the file. This line will be spliced to the previously read line
         (the current line). Every time a line is read, the line counter is incremented
         ------------------------------------------------------------------------------------------ */
         ArrayList<XString>  nextLineTokens = super.parsedLine();
         iLineNum++;
         /*.
         ==========================================================================================
         Concatenate the last token of the current line with the first token of the next line
         ------------------------------------------------------------------------------------------ */
         lastToken  = (nextLineTokens.size() > 0)? lastToken.concat(nextLineTokens.remove(0)) : lastToken;
         /*.
         ==========================================================================================
         Put the concatenated token at the end of the current line and then append all the tokens
         from the next line to the current line
         ------------------------------------------------------------------------------------------ */
         iLastLine.add(lastToken);
         iLastLine.addAll(nextLineTokens);
         }
      /*.
      ==========================================================================================
      Returned the [possibly spliced] current line
      ------------------------------------------------------------------------------------------ */
      return iLastLine;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method sets the quote character for this object.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#025">View source</A>

   @return
      A reference to this object

   @param
      pQuoteChar is the character to use as a quote for this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CsvFile setQuote(char pQuoteChar)
      {
      super.setQuote(pQuoteChar);
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method sets the delimiter character for this object.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#026">View source</A>

   @return
      A reference to this object

   @param
      pDelimiterChar is the character to use as a delimiter for this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CsvFile setDelimiter(char pDelimiterChar)
      {
      super.setDelimiter(pDelimiterChar);
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method sets the flag that determines whether or not the parseLine() method wil return the
   header line.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#027">View source</A>

   @return
      A reference to this object

   @param
      pSkipHeaderLines is the boolean value to turn on or off the skipping of header lines. If
      pSkipHeaderLines is true, then the parsedLine() will skip the header line. If false, it will not
      skip header lines.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CsvFile setSkipHeaderLine(boolean pSkipHeaderLine)
      {
      super.setSkipHeaderLine(pSkipHeaderLine);
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method tells this object whether to skip white space lines or not. A white space line is a line
   of the text file that contains only white space characters.<P>

   This method is a superset of setSkipBlankLines() because white space lines include blank lines.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#028">View source</A>

   @return
      A reference to this object

   @param
      pSkipWhiteSpaceLines is the boolean value to turn on or off the skipping of white space lines. If
      pSkipWhiteSpaceLines is true, then the TextReaderIterator will skip white space lines. If false,
      it will not skip white space lines.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CsvFile setSkipWhiteSpaceLines(boolean pSkipWhiteSpaceLines)
      {
      super.setSkipWhiteSpaceLines(pSkipWhiteSpaceLines);
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method sets the ConsoleStream for this object.

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#029">View source</A>

   @return
      A reference to this object

   @param
      pConsole is a ConsoleStream through which this objects sends its output.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CsvFile setOut(ConsoleStream pConsole)
      {
      cOut = pConsole;
      return this;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   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="CsvFile.java.html#030">View source</A>

   @return
      A reference to this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public CsvFile test() throws Exception
      {
      cOut.titledPrintf
         (
         "\"HELLO WORLD!\"",
         "%s  %s  %s",
         "I'm an object of the", CLASS_NAME, "class, and I approved this message."
         );
      return this;
      }



   /*:.
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Public Class Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Main  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   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.CsvFile
            </DD>
         </DT>
      </DL>

   <P><B>Implementation: </B><A HREF="CsvFile.java.html#031">View source</A>

   @param
      pArgs contains the command line arguments with which this class was invoked as an application.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static void main(String[] pArgs) throws Exception
      {
      /*.
      ==========================================================================================
      Greetings !
      ------------------------------------------------------------------------------------------ */
      cOut.banner(CLASS_NAME);
      /*.
      ==========================================================================================
      Create an object and send its output to the ConsoleStream
      ------------------------------------------------------------------------------------------ */
      CsvFile  testFile = new CsvFile("c:/temp/20.HPSC.Raw.csv","C:/adb/pkg/java/cosmicabyss/com/lib/Definition.SDRIncidentCsvFile.csv");
      /*.
      ==========================================================================================
      Have the instance say hello
      ------------------------------------------------------------------------------------------ */
      testFile.test();
      /*.
      ==========================================================================================
      We're going to read every line (row) of data in the file and print something out about it
      but we dont want to include the header line in that process. So tell the object to skip
      over that line abd not to return the header line on the first call to retrieve a line of
      the file.
      ------------------------------------------------------------------------------------------ */
      testFile.setSkipHeaderLine(true);
      /*.
      ==========================================================================================
      For every row of the file ...
      ------------------------------------------------------------------------------------------ */
      int i=0;
      while (testFile.hasNext())
         {
         if (i++ > 3) break;
         /*.
         ==========================================================================================
         Read the row from the file
         ------------------------------------------------------------------------------------------ */
         testFile.readNext();
         /*.
         ==========================================================================================
         ------------------------------------------------------------------------------------------ */
         testFile.println();
         }
      }



   }  // class CsvFile



   /*:.
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Notes  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */