Package Torello.Java

Class EMailLists

  • All Implemented Interfaces:
    java.io.Serializable, java.lang.Cloneable, java.util.Map<java.lang.String,​java.lang.String[]>, java.util.NavigableMap<java.lang.String,​java.lang.String[]>, java.util.SortedMap<java.lang.String,​java.lang.String[]>

    public class EMailLists
    extends java.util.TreeMap<java.lang.String,​java.lang.String[]>
    Some simple methods that make use of the Java Mail API.

    This stores e-mail addresses to a java.util.TreeMap<String, String[]> data structure. This data structure can be serialized and saved to disk. This class does not implement the interface java.io.Serializable in order to protect/guarantee that future versions of this class will be compatible with the current version. Instead, the data is cloned/copied to a parent class version of TreeMap<String, String[]>, and the java.util.TreeMap object is then written to disk. This is because the Java Language version of the class TreeMap serialization will hopefully not be changing anytime soon.

    Mostly this class can be used to save and load e-mail address to a data-base. Rather than worrying to much about the contents of this class, no names, addresses or personal information of any kind is attributed to the address, only the address itself is stored. Furthermore, the contents are automatically compressed using ZIP compression. A curious coder should visit: FileRW.writeObjectToFile(...); to see how Java's ZIP capabilities are automatically used to serialize objects in this package.

    NOTE: Again, pay close attention to the fact that this class extends the java.util.TreeMap<String, String[]> data-structure, so it's contents should be easily accessible. Mostly this sub-class provides some "syntactic simplicity" for manipulating a tree of e-mail lists. The key (java.lang.String) in this TreeMap is intended to simply be the name of list of e-mail addresses, while the value (java.lang.String[]) - of type 'Array' is intended to be a list of values.

    Example:
    EMailLists rolodex = EMailLists.createNewInstance("~/data/email.dat");
    String[] friendsFamily = { "bob@gmail.com", "mom@yahoo.com", "user987@example.com" };
    rolodex.put("Friends and Family", friendsFamily);
    String[] overseasFriends = { "Ruiz@att.net.mx", "chen123@sina.com.cn" };
    rolodex.put("Overseas", overseasFriends);
    rolodex.writeToDisk();
    
    See Also:
    Serialized Form


    • Nested Class Summary

      • Nested classes/interfaces inherited from class java.util.AbstractMap

        java.util.AbstractMap.SimpleEntry<K extends java.lang.Object,​V extends java.lang.Object>, java.util.AbstractMap.SimpleImmutableEntry<K extends java.lang.Object,​V extends java.lang.Object>
    • Constructor Summary

      Constructors 
      Modifier Description
      protected
      This loads a data-file that must have been generated by the interface Serializable.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method
      void addAddress​(String listName, String... eMailAddress)
      Vector<String> checkValidity​(boolean verbosePrint)
      Vector<String> checkValidity​(String listName, boolean verbosePrint)
      int clean​(String listName)
      int cleanEachList()
      static EMailLists createNewInstance()
      static EMailLists fromString​(String b64MimeEncoded)
      static EMailLists fromTreeMap​(TreeMap<String,​String[]> tm)
      String listsToString()
      static EMailLists loadFromDisk​(String dataFileName)
      static void main​(String[] argv)
      static void printMenu()
      String printToHTML()
      void removeAddress​(String listName, String... eMailAddress)
      String summariesToString()
      TreeMap<String,​Exception> updateList​(String listName, String newAddressListFileName)
      void writeToDisk()
      void writeToDisk​(String fileName)
      String writeToString()
      • Methods inherited from class java.util.TreeMap

        ceilingEntry, ceilingKey, clear, clone, comparator, containsKey, containsValue, descendingKeySet, descendingMap, entrySet, firstEntry, firstKey, floorEntry, floorKey, forEach, get, headMap, headMap, higherEntry, higherKey, keySet, lastEntry, lastKey, lowerEntry, lowerKey, navigableKeySet, pollFirstEntry, pollLastEntry, put, putAll, remove, replace, replace, replaceAll, size, subMap, subMap, tailMap, tailMap, values
      • Methods inherited from class java.util.AbstractMap

        equals, hashCode, isEmpty, toString
      • Methods inherited from class java.lang.Object

        finalize, getClass, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.util.Map

        compute, computeIfAbsent, computeIfPresent, equals, getOrDefault, hashCode, isEmpty, merge, putIfAbsent, remove
    • Field Detail

      • serialVersionUID

        🡇    
        public static final long serialVersionUID
        This fulfils the SerialVersion UID requirement for all classes that implement Java's interface java.io.Serializable. Using the Serializable Implementation offered by java is very easy, and can make saving program state when debugging a lot easier. It can also be used in place of more complicated systems like "hibernate" to store data as well.
        See Also:
        Constant Field Values
        Code:
        Exact Field Declaration Expression:
         public static final long serialVersionUID = 1;
        
      • DATA_FILE_NAME

        🡅  🡇    
        public final java.lang.String DATA_FILE_NAME
        This stores the name of the data-file that contains the Rolodex information. It is a compressed (ZIP-format Compression), java java.io.serializable object file containing just a single data object of type: "java.util.TreeMap<String, String[]>"
        Code:
        Exact Field Declaration Expression:
         public final String DATA_FILE_NAME;
        
    • Constructor Detail

      • EMailLists

        🡅  🡇    
        protected EMailLists​
                    (java.lang.String dataFileName,
                     java.util.TreeMap<java.lang.String,​java.lang.String[]> tm,
                     boolean newInstance)
        
        This loads a data-file that must have been generated by the interface java.io.Serializable. The contents of this data file should be just one java java.lang.Object of specific-type java.util.TreeMap<String, String[]>
        Parameters:
        dataFileName - The name of the file where data will or should be stored.
        tm - A TreeMap containing an e-mail address Rolodex.
        newInstance - This should be set to TRUE if the user intends to create a brand new instance of the EMailLists class.

        NOTE: If this variable is true, the disk-data file specified by parameter dataFileName will not be visited.

        CAUTION: If this variable is set to TRUE, but there is already an older data-file present on disk with this file-name, then that file will be over-written with the first call the programmer makes to public void writeToDisk()}.
    • Method Detail

      • loadFromDisk

        🡅  🡇    
        public static EMailLists loadFromDisk​(java.lang.String dataFileName)
                                       throws java.io.IOException
        This simply takes the file name that has been provided via the String diskFileName parameter, and loads that file to memory from disk.
        Parameters:
        dataFileName - The name of a datafile that has been stored somewhere on disk. It is stored as a java interface java.io.Serializable object file. The file that is on disk will not be of type EMailLists but rather of type java.util.TreeMap<String, String[]>, to ensure forward-compatability. This conversion is done automatically within this class by the public void writeToDisk() method.
        Returns:
        An instance of class EMailLists that has been fully instantiated and populated with the Rolodex data that is stored within the data-file identified by the data-file name provided in the parameter list.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         @SuppressWarnings("unchecked")
         TreeMap<String, String[]> tm = (TreeMap<String, String[]>) FileRW.readObjectFromFileNOCNFE
             (dataFileName, TreeMap.class, true);
        
         return new EMailLists(dataFileName, tm, false);
        
      • fromTreeMap

        🡅  🡇    
        public static EMailLists fromTreeMap​
                    (java.util.TreeMap<java.lang.String,​java.lang.String[]> tm)
        
        Loads an instance of this class from a TreeMap<String, String[]> - which may or may or may not have been generated by this class.
        Parameters:
        tm - A map of e-mail address lists.
        Returns:
        An instance of class EMailLists that has been fully instantiated and populated with the Rolodex data that is stored within the data-file identified by the data-file name provided in the parameter list.
        Code:
        Exact Method Body:
         return new EMailLists(null, tm, false);
        
      • fromString

        🡅  🡇    
        public static EMailLists fromString​(java.lang.String b64MimeEncoded)
                                     throws java.io.IOException
        Loads this Rolodex from a MIME-String
        Parameters:
        b64MimeEncoded - The internal e-mail address TreeMap data, encoded as a base 64 MIME String.
        Returns:
        An instance of this class, derived from a MIME-String encoded data.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         return new EMailLists(null, (TreeMap<String, String[]>) StringParse.b64MimeStrToObj(b64MimeEncoded), false);
        
      • createNewInstance

        🡅  🡇    
        public static EMailLists createNewInstance()
        This creates a brand new, empty "e-mail address Rolodex." This class is a sub-class of java.util.TreeMap<String, String[]>
        Returns:
        A new instance of this class.
        IMPORTANT NOTE: A data-file for this class instance will not be created. After saving some lists to this Rolodex, the user must execute a call to: public void writeToDisk() in order to check the data in this data-structure out to disk.
        Code:
        Exact Method Body:
         return new EMailLists(null, null, true);
        
      • writeToDisk

        🡅  🡇    
        public void writeToDisk()
                         throws java.io.IOException
        This saves the data-contents of this class directly to disk. It uses the interface java.io.Serializable to save the data.

        NOTE: The data stored in this class TreeMap<String, String[]>, which is indeed a parent-class that is "extended" by this (the class EMailLists), is first converted back into the parent TreeMap class. This is done for one reason, and that is regarding Java's quirks in Object serialization. If future versions of class EMailLists are written, previously serialized objects of type Torello.Java.EMailLists would cease to be readable with the serializable interface. In the method public void writeToDisk(), the contents of the Tree-Map are cloned into the parent TreeMap class, and only then are they written to disk.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if (DATA_FILE_NAME == null) throw new IllegalArgumentException(
             "This instance of EMailLists was not loaded from disk, so there is no data file-name " +
             "to write the TreeMap to."
         );
        
         TreeMap<String, String[]> temp = new TreeMap<>();
        
         temp.putAll(this);
        
         FileRW.writeObjectToFileNOCNFE(this, DATA_FILE_NAME, true);
        
      • writeToDisk

        🡅  🡇    
        public void writeToDisk​(java.lang.String fileName)
                         throws java.io.IOException
        Writes this class' internal e-mail address data to disk.
        Parameters:
        fileName - The name of the data-file to be used for writing.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         TreeMap<String, String[]> temp = new TreeMap<>();
        
         temp.putAll(this);
        
         FileRW.writeObjectToFileNOCNFE(this, fileName, true);
        
      • writeToString

        🡅  🡇    
        public java.lang.String writeToString()
                                       throws java.io.IOException
        Writes this class' internal e-mail address data to an output String.
        Returns:
        This class' internal data as a Base-64 MIME Encoded String.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         TreeMap<String, String[]> temp = new TreeMap<>();
        
         temp.putAll(this);
        
         return StringParse.objToB64MimeStr(temp);
        
      • summariesToString

        🡅  🡇    
        public java.lang.String summariesToString()
                                           throws java.io.IOException
        This This prints the names of the lists to a StringBuilder, and how many e-mail addresses are in each list.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         StringBuilder sb = new StringBuilder();
        
         for (String s : keySet())
             sb.append(StringParse.zeroPad(get(s).length) + " elements in group: " + s);
        
         return sb.toString();
        
      • listsToString

        🡅  🡇    
        public java.lang.String listsToString()
        This simply prints the contents of the underlying TreeMap data-structure using a StringBuilder, and returns the String.
        Returns:
        A String representation of the internal TreeMap
        Code:
        Exact Method Body:
         StringBuilder sb = new StringBuilder();
        
         for (String listName : keySet())
         {
             String[] list = get(listName);
        
             sb.append(
                 "************************************************************************************************************\n" +
                 "PRINTING LIST:\t" + listName + ", which has " + list.length + " elements.\n"
             );
        
             int count = 1;
             for (String eMailAddr : list) sb.append("[" + (count++) + ": " + eMailAddr + "], ");
        
             sb.append("\nThere were a total of " + (count-1) + " addresses in this subset.\n");
         }
        
         return sb.toString();
        
      • printToHTML

        🡅  🡇    
        public java.lang.String printToHTML()
                                     throws java.io.IOException
        This generates a simple, view-able, HTML file as a String. The HTML String that is returned does not contain header information, nor footer info. It is just a series of <H1> List Name </H1> followed by tables as <TABLE CLASS="EMailListsTable"> ... </TABLE>. The user needs to add opening and closing HTML tags if this is to be a complete page with well-formatted HTML.
        Returns:
        The internal e-mail Rolodex data-structure as a series of HTML tables.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         StringBuilder sb = new StringBuilder();
         sb.append("<STYLE type=\"text/css\">\n.EMailListsTable TD { width: 33%; }\n</STYLE>\n");
        
         for (String listName : keySet())
         {
             String[] list = get(listName);
             sb.append("<H1>" + listName + "</H1>\n<TABLE CLASS=\"EMailListsTable\" STYLE=\"width: 100%;\">");
        
             for (int i=0; i < list.length; i += 3)
                 sb.append(
                     "<TR>\n" +
                     "<TD>" + list[i] + "</TD>\n" +
                     "<TD>" + (i+1 < list.length ? list[i+1] : " ") + "</TD>\n" +
                     "<TD>" + (i+2 < list.length ? list[i+2] : " ") + "</TD>\n" +
                     "</TR>\n"
                 );
        
             sb.append("</TABLE>\n<BR /><BR />\n\n\n");
         }
         return sb.toString();
        
      • checkValidity

        🡅  🡇    
        public java.util.Vector<java.lang.String> checkValidity​
                    (java.lang.String listName,
                     boolean verbosePrint)
        
        This does a simple validity check by attempting to instantiate each e-mail address stored in the String[] e-mail address String Arrays within the TreeMap by performing this instantiation: new javax.mail.internet.InternetAddress(eMailAddress);

        If the above line of code throws an Exception, then this will be identified as an "invalid e-mail address" and returned with the result set. Invalid e-mail addresses are not removed from the data-structure, but rather, they are returned with the result set.

        If the parameter boolean verbosePrint is set to TRUE, messages will be sent to System.out.println(...)
        Parameters:
        listName - The name of the list whose String[] Array contents need to be checked here.
        verbosePrint - When TRUE, messages will be sent to System.out
        Returns:
        A list of potentially improperly formed e-mail addresses.
        Code:
        Exact Method Body:
         Vector<String> ret = new Vector<String>();
        
         for (String emailAddress : get(listName))
             try
                 { InternetAddress ia = new InternetAddress(emailAddress); System.out.print("."); }
             catch (Exception e)
             {
                 if (verbosePrint) System.out.println(
                     "\nE-Mail Address:\t[" + emailAddress + "] from list:\t[" + listName + "] " +
                     "generated an Exception!"
                 );
        
                 ret.addElement(emailAddress);
             }
        
         return ret;
        
      • checkValidity

        🡅  🡇    
        public java.util.Vector<java.lang.String> checkValidity​
                    (boolean verbosePrint)
                throws java.io.IOException
        
        This performs the validity check on each and every list in this TreeMap data-structure. It calls the method checkValidity(String, boolean)
        Parameters:
        verbosePrint - When TRUE, messages will be sent to System.out
        Returns:
        A list of potentially improperly formed e-mail addresses.
        Throws:
        java.io.IOException
        See Also:
        checkValidity(String, boolean)
        Code:
        Exact Method Body:
         Vector<String> ret = new Vector<String>();
        
         for (String listName : keySet())
         {
             if (verbosePrint) System.out.print("Working list: " + listName);
        
             ret.addAll(checkValidity(listName, verbosePrint));
        
             if (verbosePrint) System.out.println();
         }
        
         return ret;
        
      • clean

        🡅  🡇    
        public int clean​(java.lang.String listName)
        NOTE: The original name of this function was removePossibleDuplicatesAndSort(String), but was shortened to just "clean"

        This will go through the contents of the list identified by 'listName', and ensure there are no duplicate e-mail addresses. If there are, they will be removed. The arrays are also sorted. Each address stored in the String Arrays is converted to lower-case text, and trimmed.

        NOTE: If this list has been modified, it is up to the user/programmer to write the changes to the disk data-file. Disk data-file writes are not done automatically. You need to concern yourself with this aspect.
        Parameters:
        listName - The name of the String[] list in the underlying java.util.TreeMap<String, String[]> data-structure whose contents need to be pruned.
        Returns:
        The number of e-mail addresses that were removed from this subset of the Rolodex, because there were duplicates present.
        Code:
        Exact Method Body:
         String[]        list        = get(listName);
         TreeSet<String> ts          = new TreeSet<String>();
         int             oldLength   = list.length;
        
         for (int i=0; i < oldLength; i++) ts.add(list[i].toLowerCase().trim());
        
         put(listName, ts.toArray(new String[0]));
        
         return oldLength - ts.size();
        
      • cleanEachList

        🡅  🡇    
        public int cleanEachList()
        The original name of this function was removePossibleDuplicatesAndSort(String), but was shortened to just 'cleanEachList()'. This will remove all duplicates from each and every list in the TreeMap. The arrays will also be sorted. Each address stored in the String[] array's is converted to lower-case text, and trimmed.
        IMPORTANT NOTE: This will removed duplicates that are identified on a on a "list by list" basis. This means that in the case where there are two identical e-mail addresses in a single list, one will be removed. HOWEVER, if a single e-mail address is present in multiple, different lists, this method will not catch that scenario as a mistake. If the programmer considers this scenario a mistake, it should be important to remember that the underlying TreeMap<String, String[]> data-structure is perfectly visible (as a super-class), and therefore can be modified in whatever way 3rd-party programmers wish to change the contents of this data-structure.

        The clean methods in this class are just designed to make sure that the arrays themselves do not have multiple copies of the same address, because that is a guaranteed "programmatically incorrect" scenario. Having a single address distributed in multiple lists, however, might easily a desired situation for some programmers.

        This is why the method is called "cleanEachList" instead of just "clean" or "cleanAll" - since they are done sequentially.
        Returns:
        The total number of e-mail addresses that were duplicates and were removed from all lists in this Rolodex.
        Code:
        Exact Method Body:
         int total = 0;
        
         for (String listName : keySet()) total += clean(listName);
        
         return total;
        
      • addAddress

        🡅  🡇    
        public void addAddress​(java.lang.String listName,
                               java.lang.String... eMailAddress)
        This will add the given e-mail address(es) to the specified list in this data structure. The list that is stored back into the String[] Array will be sorted, and the String elements will be made to lower-case text, and trimmed (using java.lang.String.trim()).
        Parameters:
        listName - The name of the already-existing list in this TreeMap.
        eMailAddress - One or more e-mail addresses to be added to this list
        Throws:
        java.lang.IllegalArgumentException - This will throw an exception if:

        • This String[] Array specified by parameter 'listName' in the TreeMap already contains a copy of this e-mail address
        • The passed parameter String[] eMailAddress has multiple copies of the same address
        • The instantiation new javax.mail.internet.InternetAddress(eMailAddress) generates an exception
        Code:
        Exact Method Body:
         TreeSet<String> ts      = new TreeSet<String>();
         String[]        curList = get(listName);
        
         for (String address : curList) ts.add(address.trim().toLowerCase());
        
         for (String address : eMailAddress)
         {
             try
                 { new InternetAddress(address = address.trim().toLowerCase()); }
             catch (Exception e)
             {
                 throw new IllegalArgumentException(
                     "E-Mail Address: [" + address + "] is not a valid address.  It generated an " +
                     "exception:\n" + e.getMessage()
                 );
             }
        
             if (! ts.add(address)) throw new IllegalArgumentException
                 ("E-Mail Address: [" + address + "] is already in the list: [" + listName + "]");
         }
        
         put(listName, ts.toArray(new String[0]));
        
      • removeAddress

        🡅  🡇    
        public void removeAddress​(java.lang.String listName,
                                  java.lang.String... eMailAddress)
        Removes the specified e-mail addresses from the list specified by the String listName parameter.
        Parameters:
        listName - The name of the already-existing list in this TreeMap.
        eMailAddress - One or more e-mail addresses to be added to this String[] Array e-mail address list.
        Throws:
        java.lang.IllegalArgumentException - This will throw an exception if one or more of the requested addresses to be removed is/are not actually present in the underlying String[] Array associated with listName.
        Code:
        Exact Method Body:
         TreeSet<String> ts      = new TreeSet<String>();
         String[]        curList = get(listName);
        
         for (String address : curList) ts.add(address.trim().toLowerCase());
        
         for (String address : eMailAddress)
             if (! ts.remove(address = address.trim().toLowerCase()))
                 throw new IllegalArgumentException
                     ("E-Mail Address: [" + address + "] is not in the list: [" + listName + "]");
        
         put(listName, ts.toArray(new String[0]));
        
      • updateList

        🡅  🡇    
        public java.util.TreeMap<java.lang.String,​java.lang.Exception> updateList​
                    (java.lang.String listName,
                     java.lang.String newAddressListFileName)
                throws java.io.IOException
        
        This will create a new section in the Rolodex with the name of this list. If the Rolodex already contains a list by this name, the two lists will be merged.
        Parameters:
        listName - This is the name "Rolodex subsection." It is an element in the TreeMap, and contains one list of e-mail addresses.
        newAddressListFileName - This is a list of e-mail addresses, stored in a text-file. The name of the text-file to load may be provided here. The format of the file expects new addresses to be included, one per line.
        Returns:
        Whether updating a list that already exists, or creating a brand new list - the e-mail addresses that are found in the text file ('newAddressListFileName') will be checked for validity. Checking for validity simply means calling Java's class InternetAddress constructor, and waiting to see if the address may be instantiated, or if it generates an exception. If an exception does occur, that address will be skipped, and the exception will be saved in the response TreeMap.

        The response tree-map simply contains a list of the e-mail addresses that were problems to instantiate with the class javax.mail.internet.InternetAddress in the TreeMap key field. In the lookup/value field of the TreeMap, the exception that was generated will be provided.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         TreeSet<String>             ts                  = new TreeSet<String>();
         String[]                    curAddrList         = get(listName);
         TreeMap<String, Exception>  errors              = new TreeMap<>();
         Vector<String>              newAddrList         = FileRW.loadFileToVector(newAddressListFileName, false);
        
         // Make sure that all the elements in the old list (if there is one!) are trimmed and lower-case
         if (curAddrList != null)
             for (String addr : curAddrList) ts.add(addr.trim().toLowerCase());
        
         // Make sure all the newly loaded e-mail addresses are trim/lower-case
         newAddrList.replaceAll(addr -> addr.trim().toLowerCase());
        
         // Make sure that each new address does not cause an exception when instantiating.
         for (String addr : newAddrList)
             try                 { new InternetAddress(addr.trim().toLowerCase()); }
             catch (Exception e) { errors.put(addr, e); }
        
         // Add only the "safe addresses" to this list.
         for (String addr : newAddrList) if (! errors.containsKey(addr)) ts.add(addr);
        
         // Convert the new list to an array
         String[]                    newAddrListAsArr    = new String[ts.size()];
         int                         i                   = 0;
        
         for (String addr : ts) newAddrListAsArr[i++] = addr;
         put(listName, newAddrListAsArr);
        
         if (errors.size() > 0) return errors; else return null;
        
      • printMenu

        🡅  🡇    
        public static void printMenu()
        Facilitates a (very) small console-driven menu for adding and removing addresses to specific lists. At the BASH/UNIX/MS-DOS console, execute a call to: java Torello.Java.EMailLists to see this printMenu() help menu command output. Follow instructions from there.

        NOTE: Menu Option #1 will ask you to specify the name of your e-mail list data-file. It will not create one for your, but rather, just save that file-name to a temporary text-file in your current working directory. This will be used for the duration of your console session.
        Code:
        Exact Method Body:
         System.out.println(
             "1: set temporary text-file pointer  ... SPECIFICALLY: argv[0]=\"1\", argv[1]=your-email-data-file-name" +
             "2: printLists();" +
             "3: addAddress(argv[1], argv[2]);    ... SPECIFICALLY: argv[0]=\"3\", argv[1]=list-name, argv[2]=e-mail address" +
             "4: removeAddress(argv[1], argv[2]); ... SPECIFICALLY: argv[0]=\"4\", argv[1]=list-name, argv[2]=e-mail address"
         );
        
         System.exit(0);
        
      • main

        🡅    
        public static void main​(java.lang.String[] argv)
                         throws java.io.IOException
        This will facilitate a (very) small console-driven command program to add or remove e-mail lists to and from already existent lists. If incorrect command-line arguments are not provided, the help menu is printed to console.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if (argv.length < 1) printMenu();
                
         if (argv[0].equals("1"))
             if (argv.length != 2)   printMenu();
             else                    FileRW.writeFile(argv[1] + "\n", "EMAIL_LISTS_TEMP_FILE.txt");
        
         EMailLists lists = EMailLists.loadFromDisk
             (FileRW.loadFileToString("EMAIL_LISTS_TEMP_FILE.txt").trim());
        
         if (argv[0].equals("2"))
             if (argv.length != 1)   printMenu();
             else                    System.out.print(lists.listsToString());
        
         if (argv[0].equals("3"))
             if (argv.length != 3)   printMenu();
             else                    { lists.addAddress(argv[1], argv[2]); lists.writeToDisk(); }
        
         if (argv[0].equals("4"))
             if (argv.length != 3)   printMenu(); 
             else                    { lists.removeAddress(argv[1], argv[2]); lists.writeToDisk(); }