Package Torello.Java
Class EMailLists
- java.lang.Object
-
- java.util.AbstractMap<K,V>
-
- java.util.TreeMap<java.lang.String,java.lang.String[]>
-
- Torello.Java.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 ajava.util.TreeMap<String, String[]>
data structure. This data structure can be serialized and saved to disk. This class does not implement theinterface 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 ofTreeMap<String, String[]>
, and thejava.util.TreeMap
object is then written to disk. This is because the Java Language version of theclass 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 thejava.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. Thekey (java.lang.String)
in thisTreeMap
is intended to simply be the name of list of e-mail addresses, while thevalue (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
Hi-Lited Source-Code:- View Here: Torello/Java/EMailLists.java
- Open New Browser-Tab: Torello/Java/EMailLists.java
-
-
Field Summary
Fields Modifier and Type Field String
DATA_FILE_NAME
static long
serialVersionUID
-
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
-
-
-
-
Field Detail
-
serialVersionUID
public static final long serialVersionUID
This fulfils the SerialVersion UID requirement for all classes that implement Java'sinterface java.io.Serializable
. Using theSerializable
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 theinterface java.io.Serializable
. The contents of this data file should be just one javajava.lang.Object
of specific-typejava.util.TreeMap<String, String[]>
- Parameters:
dataFileName
- The name of the file where data will or should be stored.tm
- ATreeMap
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 parameterdataFileName
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 topublic 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 theString 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 ajava interface java.io.Serializable
object file. The file that is on disk will not be of typeEMailLists
but rather of typejava.util.TreeMap<String, String[]>
, to ensure forward-compatability. This conversion is done automatically within this class by thepublic 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 aTreeMap<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 addressTreeMap
data, encoded as a base 64 MIMEString
.- 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 ofjava.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 theinterface java.io.Serializable
to save the data.
NOTE: The data stored in thisclass TreeMap<String, String[]>
, which is indeed a parent-class that is "extended" by this (theclass EMailLists
), is first converted back into the parent TreeMap class. This is done for one reason, and that is regarding Java's quirks inObject
serialization. If future versions ofclass EMailLists
are written, previously serialized objects of typeTorello.Java.EMailLists
would cease to be readable with the serializable interface. In the methodpublic 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 outputString
.- 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 aStringBuilder
, 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 underlyingTreeMap
data-structure using aStringBuilder
, and returns theString
.- 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 aString
. The HTMLString
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 theString[]
e-mail addressString 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 parameterboolean verbosePrint
is set to TRUE, messages will be sent toSystem.out.println(...)
- Parameters:
listName
- The name of the list whoseString[] Array
contents need to be checked here.verbosePrint
- When TRUE, messages will be sent toSystem.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 thisTreeMap
data-structure. It calls the methodcheckValidity(String, boolean)
- Parameters:
verbosePrint
- When TRUE, messages will be sent toSystem.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 wasremovePossibleDuplicatesAndSort(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 theString 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 theString[] list
in the underlyingjava.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 wasremovePossibleDuplicatesAndSort(String)
, but was shortened to just'cleanEachList()'
. This will remove all duplicates from each and every list in theTreeMap
. The arrays will also be sorted. Each address stored in theString[] 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 underlyingTreeMap<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 theString[] Array
will be sorted, and theString
elements will be made to lower-case text, and trimmed (usingjava.lang.String.trim()
).- Parameters:
listName
- The name of the already-existing list in thisTreeMap
.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 theTreeMap
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
- This
- 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 theString listName
parameter.- Parameters:
listName
- The name of the already-existing list in thisTreeMap
.eMailAddress
- One or more e-mail addresses to be added to thisString[] 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 underlyingString[] Array
associated withlistName
.- 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 theTreeMap
, 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'sclass 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 responseTreeMap
.
The response tree-map simply contains a list of the e-mail addresses that were problems to instantiate with theclass javax.mail.internet.InternetAddress
in the TreeMap key field. In the lookup/value field of theTreeMap
, 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 thisprintMenu()
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(); }
-
-