Project 5 — You've Got Mail: The Real Thing
|
![]() |
In this final phase of the evolving mail program, you will be expanding and adapting the class hierarchy from Project 4. We are providing a set of libraries that will give you the necessary infrastructure support to access actual mail servers over the internet. These libraries have their own models of how a class hierarchy should look for mail access. Your job is to interface your existing system to this model. This will likely require you to modify your own class hierarchy to fit gracefully with the libraries we provide. The better you planned ahead when you were designing the MailRepository class hierarchy, the easier and more logical the update wil be.
This project requires an about-face from the way Projects 2, 3, and 4 were evolving: for that set, we were having you gradually implement your own layers of a multi-layer model, replacing out parts that we provided for you with ones you designed and implemented yourself. However, in the real world, you rarely develop monolithic programs in isolation. Instead, you work in teams, or work on extensions to legacy projects. That involves being able to adapt to other people's packages, classes, and interfaces. That's an important skill to develop.
At the end of this project, you will have a working Java application that you can use to access pretty much any network-based mailbox out there. You should be able to access UMBC mail, Gmail, etc. That's pretty cool.
This project mainly involves expanding the stub classes you started designing in Project 4 to anticipate network-based mail stores. We are providing a set of libraries that manages the more technical parts of interacting with an actual Internet mail server machine: the network connection setup and management, the handshaking protocols, resource management, etc. On top of existing Java libraries, we have layered our own interface that goes part-way towards matching the model we have been working from in our class projects. However, this is just a foundation that you need to build further on top of.
At the end of Project 4, you had a working program, comprising the EmailClient class, plus the MailRepository class hierarchy. As part of that, you had to program up a concrete implementation of the file-based extension of the MailRepository class. You also had to have skeletal versions of a NetworkMailRepository. You will now be building that out. The goal is to be to do all the things with NetworkMailRepository that you were able to do with FileMailRepository.
EmailClient
classpublic EmailClient(String host, String type, int port, String mailbox)This should be in addition to your existing constructor for setting up a file-based mailbox: do not delete that other constructor!
EmailClient should be extended to have logic for alternatively constructing a new FileMailRepository or a NetworkMailRepository or some subclass of that. However, as before, you should then assign the instance to a reference variable declared to be just MailRepository, and the rest should be transparent. Not much else will change.
MailRepository
subclassesFileMailRepository
class; it should work exactly as
it is (assuming it currently works! :-) ) However, you might find that
there are some parts of FileMailRepository, especially the parsing
functionality, that might be very useful for handling POP3 mail
servers, because our libraries are (purposefully) deficient in that
area. So, you might want to abstract out some of the methods, make
them static
, and place them in a utility class like
MailRepositoryUtil, so that the code can be shared by methods in
the FileRepository class and the Pop3MailRepository class.
That's it for Project 5. Good luck!
We are providing a pair of .jar files. Look back at the instructions
for previous projects to see how to incorporate them into your build
path for Eclipse, or how to unpack them into your working directory for
compiling manually. The archive
proj5Lib.jar contains the classes
NetworkMailbox
and MailMessage
; you will also
need the archive mail.jar which contains
the Java mail library that proj5Lib is built upon.
Here are the declarations for the classes and methods we are providing for Project 5. A couple of important points:
proj5Lib
--
this is a compact package, so it is safe to just
"import proj5Lib.*
".
NetworkMailbox
and MailMessage
classes potentially throw one of four
exception types:
UnsupportedOperationException
MailboxException
, with subclasses:
MailboxOpenException
MailboxContentException
Here are the summaries of the two main classes you will be using. You will not be calling any constructors of either:
NetworkMailbox
class:NetworkMailbox.openNetworkMailbox
which will return an instance of some subclass of NetworkMailbox
(but you will just declare all of your reference variables to be of type
NetworkMailbox
)
package proj5Lib; public abstract class NetworkMailbox { public static String IMAP = "imap"; public static String POP3 = "pop3"; // A factory method for creating an appropriately-subclassed // NetworkMailbox based on the various mailbox parameters. // @param host: the server name (e.g.: "imap.umbc.edu" // @param type: either NetworkMailbox.IMAP, or NetworkMailbox.POP3 // // The rest of the parameters have good defaults, so you can // just plug in 0 or null as appropriate: // @param port: if "0", will guess best port# based on protocol // @param mailbox: the mailbox name to open; if null, will use "INBOX" // @param username: if null, will prompt user at runtime // @param password: if null, will prompt user at runtime // // (There is another version of this that gives finer control // over SSL treatment--ask me if you are having problems with // this with your test mail server.) public static NetworkMailbox openNetworkMailbox(String host, String type, int port, String mailbox, String username, String password) throws MailboxOpenException; // Some simple accessors public String getHostname(); public String getUsername(); // Returns the number of messages in the mailbox; in the case // of IMAP servers, this includes any items that are marked for // eventual deletion. public int getNumMessages() throws MailboxException; // Fetches the n-th mail item from the mailbox. Note that // the index starts from 0, while your interface should present // the user with numbering starting from 1. public MailMessage getMessage(int index) throws MailboxException; // "Deletes" the nth mail item. In the case of POP3 mailboxes, // this deletes immediately (and the later items are thus renumbered), // while for IMAP mailboxes, this just changes the status to "D" // for "Deleted", with these items actually expunged when // commitChanges() is invoked. // Returns the message's previous "isDeleted" status. public boolean deleteMessage(int index) throws MailboxException; // For IMAP mailboxes, actually expunges items marked for deletion. // Does nothing on POP3 mailboxes. // Returns "true" if everything went okay. public boolean commitChanges() throws MailboxException; }
MailMessage
class:MailMessage
.
NB: many of the methods in this class, in addition to the specific
exceptions they are explicitly declared to throw
,
also potentially throw UnsupportedOperationException
.
This is not a checked exception, so, the compiler will not enforce
the "catch-or-declare" rule on this one. However,
it is still important that you explicitly deal with it in your code.
Another note: The more sharp-eyed among you will probably also notice that
getFromAddr()
from previous projects is now getFromAddrs();
this is because real mail systems
allow messages to be broadcast to multiple recipients.
package proj5Lib; public abstract class MailMessage { /** * Name: getFromAddr * PreCondition: None. * PostCondition: None. * @return the "From:" header field for the mail item * @throws MailboxException either when the operation is unsupported * by the protocol (e.g., POP3), or there is an internal or server * error. * (Also throws UnsupportedOperationException for POP3 servers.) */ public String getFromAddr() throws MailboxException; /** * Name: getToAddrs * PreCondition: None. * PostCondition: None. * @return the values in the "To: " header field for the mail item; * note that there may be multiple addresses, separated by ',' * @throws MailboxException either when the operation is unsupported * by the protocol (e.g., POP3), or there is an internal or server * error. * (Also throws UnsupportedOperationException for POP3 servers.) */ public String getToAddrs() throws MailboxException; /** * Name: getSentDate * PreCondition: None. * PostCondition: None. * @return the "Date:" header field for the mail item * @throws MailboxException either when the operation is unsupported * by the protocol (e.g., POP3), or there is an internal or server * error. * (Also throws UnsupportedOperationException for POP3 servers.) */ public String getSentDate() throws MailboxException; /** * Name: getSubject * PreCondition: None. * PostCondition: None. * @return the "Subject:" header field for the mail item * @throws MailboxException either when the operation is unsupported * by the protocol (e.g., POP3), or there is an internal or server * error. * (Also throws UnsupportedOperationException for POP3 servers.) */ public String getSubject() throws MailboxException; /** * Name: getStatus * PreCondition: None. * PostCondition: None. * @return the status flags for the mail item * @throws MailboxException when there is an internal or server * error. */ public abstract String getStatus() throws MailboxException; /** * Name: getHeaderText * This method returns the full set of header fields, in "FIELD: value\n" * format. You should be able to apply a general header parser to the * returned value. Some of the header fields will be continued * across multiple lines, just as with your file-based header. * PreCondition: * PostCondition: * @return The full block of header fields, in "FIELD: value\n" format. * @throws MailboxException when there is an internal or server * error. */ public String getHeaderText() throws MailboxException; /** * Name: getBodyText * PreCondition: * PostCondition: * @return The full text of the body of the mail item. Note that * since your programs for Project 5 cannot handle non-text or * multi-part mail messages, this method throws an exception in * those cases, which you should handle appropriately. * @throws MailboxContentException when the body is not simple text * @throws MailboxException when there is an internal or server * error. */ public String getBodyText() throws MailboxException, MailboxContentException; }
You are not to use any classes other than those in the standard Java libraries, and those specifically provided by me, without first checking with me.
Then, use your favorite mail client program (e.g.: Thunderbird, or the my.umbc.edu web interface) to go into your UMBC account, create a separate folder ON THE UMBC SERVER (i.e., not local to your own personal computer), and copy these email messages to that folder.
Lastly, copy the invocation of NetworkMailbox.openNetworkMailbox()
from testClient.java as a template, replacing the string "PROJ5-TEST"
with the name of your own folder. That should do it!
Here is a repeat of the downloadable resources refered and linked to in various places above:
NetworkMailbox
and MailMessage
EmailClient
class will not have changed much,
the output should be much as it was in Project 3.
There are no extra credit options for this project.
The standard grading rules will apply to this project.
Important Note:
When I provide any .jar files for the project, unless you
are an expert with JREs and classpaths, the easiest process is to
unpack the class files into your tree. To do this, from the same directory
as above, just type:
jar xf proj3UtilLib.jar
where you would replace "proj3UtilLib.jar" with whatever jar file you
are using.
To submit your project, type the command
Do not submit the provided library or test input file--we have those already :-)
More complete documentation for submit and related commands can be found here.
Remember -- if you make any change to your program, no matter how insignificant it may seem, you should recompile and retest your program before submitting it. Even the smallest typo can cause errors and a reduction in your grade.