Email attachments (by Matt DeJongh)

In this project you will extend your mail-system from Project 1 (spam filter) to handle
e-mail attachments such as pictures, text files, and pdf files.

Part 1

Create a class named Attachment which will model an email attachment.
Attachments have two attributes: a filename and a size (in kilobytes).
Create subclasses for each of the three following attachment types:

Pictures have a description, and height and width (in pixels).
Text files have unformatted text.
PDF files have a title and a description.
Implement a preview method that prints all the known details about an
Attachment. For an Attachment of unknown type, this method will just print
the filename and size. For an Attachment of known type, the method will also
print the relevant details.

Override the boolean equals(Object o) method in all four classes. Create a
unit test class for each of the four classes to test the equals method.

Modify the MailItem, MailClient and MailSystem classes so that a user can
send emails with or without mulitple attachments. If the user prints an
email with an attachment, report all the known details about the attachment
using the preview method.

Part 2

We are now going to enhance our mail-system to recognize filename extensions
and create the appropriate kind of Attachment:

Any filename with the extension "jpg" should be treated as a Picture.
Any filename with the extension "txt" should be treated as a Text file.
Any filename with the extension "pdf" should be treated as a PDF file.
Filenames with any other extension should be treated as attachments of
unknown type.
Add a class method to the Attachment class that can be used to create
Attachments. It should have the following signature:

/**
* Create an Attachment of the appropriate type given the filename extension.
* @param filename The filename for the Attachment.
* @param size The size of the Attachment (in kilobytes).
* @param otherDetails An array of other details about the Attachment. For
pictures
* this array will have three elements: description, height and width. For
* text files this will have one element: the unformatted text. For pdf files
* this will have two elements: a title and a description.
* For any other file type we ignore the otherDetails.
*/
public static Attachment createAttachment(String filename, long size,
String[] otherDetails);

This is an example of a factory method - it manufactures Attachments of the
appropriate type. Now make the constructors of the Attachment, Picture, Text
file and PDF file subclasses protected - that way you force classes from
other packages to use your factory method.

Next, we need to create Applications that can open Attachments. We need
three kinds of Applications for the three known types of files: a
PhotoViewer, a TextEditor, and a PDFReader. We also want the capability of
registering new applications for new types of files.

Create an abstract class named Application. It should define an abstract
method with the following return type and parameter:

void open(Attachment theAttachment)

Create subclasses of Application for PhotoViewer, TextEditor, and PDFReader.
Implement the open method in each subclass so that it prints out something
relevant to the attachment, e.g., for a Picture attachment with
description="a beautiful landscape", height=480, and width=640, the
PhotoViewer could print:

I am the PhotoViewer. You are viewing a picture of a beautiful landscape. It
is 640 pixels by 480 pixels.

Part 3

Add two static methods to the Application class:

A method to register applications. This method should take a filename
extension (e.g., "jpg") and an instance of an Application (e.g., a
PhotoViewer), and store the mapping.
A method to handle attachments. This method should take an Attachment,
determine its filename extension, retrieve the appropriate instance of
Application stored for that extension, and invoke the open method on it. If
there is no Application registered for the filename extension, this method
should print an appropriate warning.
Make sure that you implement these methods in a way that makes it possible
to register and use new types of Applications without modifying the methods.