CS 51Homework Laboratory # 10
Spam, Spam, Spam

Objective: To gain experience with Strings.

What is spam? Before the mid-90s, Spam was a canned "meat" product, which, I think, actually still exists under that name. Others are fondly reminded of a Monty Python skit involving a restaurant that served spam in all of its dishes. Of course, these days, the term "spam" means just one thing - unwanted mail often having to do with enlarging body parts that you might or might not have! There is lots more information available online about the history of the term "spam". Hormel (the makers of Spam) have an amusing site to give spam back its "good" reputation, including the slogan (Spam. So good...it's gone.)

This week you will build a program that should give you insights into how you might add a spam filter capability to a mail program. Our spam filter is rather simple. The user provides a list of words. The program then searches the "from" and "subject" headers of all your mail messages and divides your mail into two lists. One list contains words in the filter, the other does not.

The SpamFilter program is shown below:

In this program, the user selects the machine to read mail from, then enters their username and password. The program connects to the mail server and downloads the headers of all the messages. Initially, all the mail is considered good mail (not spam).

The user can then add filter words. The filter words appear in the text area in the top right after they are entered. When the user adds a filter word, it appears in the list, but also the mail is scanned for occurrences of the filter word. Messages with those word in their headers are removed from the good mail list and moved to the spam list.

The JComboBox at the bottom of the screen allows the user to switch between viewing the good mail or the spam.

You can use this program to connect to your actual mailbox and filter your own mail by entering your mail server name, username and password into the user interface. I provide the code to actually communicate with a mail server. You do not need to worry about errors in your program causing problems with your real mailbox, though, as there is nothing in your program that modifies your mailbox in any way.

If you don't want to use your actual mailbox, I have set up temporary mailboxes for you to use on the mail server imap.dci.pomona.edu. You would connect with the same username and password that you use to connect to your Pomona e-mail account. Of course, these mailboxes are probably currently empty. So, you will need to send yourself a few short pieces of mail to test out your program, using an address of the form abc02009@cs.pomona.edu for example.

As usual, you should bring a copy of your program design to be graded at the beginning of the lab period. The only class you will be writing is SpamFilter, as I will provide the other two classes.

The Design

I provide a MailConnection class that manages the communication with a mail server. I also provide a simple Mail class that you can use to store and retrieve a from header and a subject header. It provides the following:

public Mail (String from, String subject)
Constructs a mail object with just a from header and a subject header.

public String getFrom()
Returns the from header that was passed in on construction.

public String getSubject()
Returns the subject header that was passed in on construction.

The MailConnection class is a bit more interesting. Here are descriptions of the constructor and methods you will need to use:

public MailConnection (String host, String userName, char[] password)
To talk to your mail server, you must first construct a MailConnection object. You will pass in the name of your mail server, something like "imap.dci.pomona.edu", your login id, and your password. Notice that the password parameter is a character array rather than a String. This is not really a problem, because the GUI component that the user types their password into (a JPasswordField) returns a character array, rather than a String, so you will just pass the contents of the password field on to the MailConnection constructor.

When you construct a MailConnection it attempts to connect to the mail server. There are a number of reasons why it might fail. For example, the user might mistype his/her login id or password or the mail server might not be running for some reason. If any of these failures occur, a dialog box will popup to inform the user. Your program must also be aware that the connection failed because it will not be possible to look at the mail if there is no connection. For that reason, I provide the following method.

public boolean isConnected()
Returns true if the program currently has a connection to the mail server.

public void disconnect()
Closes the connection to the mail server. This does nothing if there is no active connection.

public int getNumMsgs()
Returns the number of messages in the mailbox you are connected to. This returns 0 if there is no active connection.

public String header (int msg)
Returns the headers of a mail message identified by the number passed in. Unlike Java, mailboxes number messages beginning with 1 and going up to the number of messages contained in the mailbox.

The mail headers are returned in one long string, such as:

From BJP04747@pomona.edu  Fri Oct 14 15:05:16 2005
Return-Path: <BJP04747@pomona.edu>
X-Original-To: kim@cs.pomona.edu
Delivered-To: kim@cs.pomona.edu
Received: from psmtp.com (exprod7og5.obsmtp.com [64.18.2.125])
        by suntop.dci.pomona.edu (Postfix) with SMTP id E51A11B9671
        for <kim@cs.pomona.edu>; Fri, 14 Oct 2005 15:05:15 -0700 (PDT)
Received: from source ([134.173.71.128]) by exprod7ob5.obsmtp.com ([64.18.6.12])
 with SMTP;
        Fri, 14 Oct 2005 15:05:10 PDT
X-MimeOLE: Produced By Microsoft Exchange V6.5.7226.0
Content-class: urn:content-classes:message
MIME-Version: 1.0
Content-Type: multipart/mixed;
        boundary="----_=_NextPart_001_01C5D10B.189304F8"
Subject: Spreadsheet for Computer Sci interest
Date: Fri, 14 Oct 2005 15:03:23 -0700
Message-ID: <C96BA1D796DA1C4E9E4B0D73686CB6D1011F8BA6@EVSFACULTYSTAFF.campus.pom
ona.edu>
X-MS-Has-Attach: yes
X-MS-TNEF-Correlator: 
Thread-Topic: Spreadsheet for Computer Sci interest
Thread-Index: AcXRCxh32gY7hsS/SImAXSPXzmfp/A==
From: "Bruce Poch" <BJP04747@pomona.edu>
To: "Kim Bruce" <kim@cs.pomona.edu>
X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on 
        suntop.dci.pomona.edu
X-Spam-Level: 
X-Spam-Status: No, score=0.8 required=2.5 tests=AWL,FORGED_RCVD_HELO,
        FROM_ENDS_IN_NUMS,HTML_50_60,HTML_MESSAGE,HTML_TEXT_AFTER_BODY,
        HTML_TEXT_AFTER_HTML autolearn=disabled version=3.0.3
X-Sanitizer: This message has been sanitized!
X-Sanitizer-URL: http://mailtools.anomy.net/
X-Sanitizer-Rev: $Id: Sanitizer.pm,v 1.90 2005/01/04 20:30:13 bre Exp $
Status: RO
X-Status: 
X-Keywords:                 
X-UID: 1970

Your spam filter will look at only the "From" and "Subject" headers. Part of your job, described below, is to extract just those headers from the long header list that header returns.

header returns an empty string if it is called when there is no connection.

Your job is to create the SpamFilter class that interacts with the MailConnection class to search the "From" and "Subject" headers for keywords indicating the message is spam. I will provide the GUI for the SpamFilter class. The GUI components that you will need to interact with are:

JTextArea mailArea
This is the main text area where the user's good mail headers or spam headers are displayed.

JComboBox goodOrSpam
This is the menu at the bottom of the screen that allows the user to control whether mailArea displays the headers from good mail or from spam. When the user makes a selection from this menu, what is displayed should change if the user's mail has already been downloaded. If no mail has been downloaded, nothing should happen.

JTextField filterField
This is the text field where the user enters a filter to be added to or removed from the list of filters.

JTextArea filterArea
This is the text area showing all the terms actively used as filters. Each filter the user adds should be displayed on a separate line within this text area.

JButton addFilterButton
This is the button labelled "Add to filter". When the user clicks this button, the entry in filterField should be added to filterArea. The filterField should be cleared. If the user's mail has already been downloaded, it should be refiltered and mailArea should be updated to show the results of the filtering.

JButton removeFilterButton
This is the button labelled "Remove from filter". When the user clicks this button, the entry in filterField should be removed from filterArea. The filterField should be cleared. If the user's mail has already been downloaded, it should be refiltered and mailArea should be updated to show the results of the filtering. If the entry in the text field does not exist in the filters, nothing should happen.

JComboBox servers
This is the menu where the user selects the mail server to connect to. Note that the user can type in the name of the server to connect to a server not in the original menu.

JTextField user
This is the text field where the user types in his/her name to connect to a mailbox.

JPasswordField pass
This is where the user types in his/her password. A JPasswordField is very similar to a JTextField except that what the user types is not displayed on the screen. Also, you will use the getPassword() method to find out what the user typed in this field, rather than getText().

JButton connectButton
This is the button labelled "Get mail". When the user clicks this button, you should create a new mail connection using the information in servers, user, and pass. You should then download headers from all of the user's mail and save just the "From" and "Subject" headers. Then close the connection to the mail server. Finally, filter the saved mail headers into good mail or spam using the current filters. Then, display good mail or spam depending on the setting of the goodOrSpam menu.

You must provide:

Implementation Suggestions

I suggest that you approach this problem in the following order:

Submitting Your Work

When your work is complete you should deposit in the appropriate dropoff folder a copy of the entire SpamFilter folder. Before you do this, make sure the folder name includes the phrase "Lab 10" and your name. Also make sure to double check your work for correctness, organization and style. This assignment is due Thursday at 11 PM as usual.

Grading Point Allocations

Value
Feature
Design preparation (3 pts total)
1 pt. instance vbles & constants
2 pts. methods
Syntax Style (5 pts total)
2 pts. Descriptive comments
1 pt. Good names
1 pt. Good use of constants
1 pt. Appropriate formatting
Semantic style (7 pts total)
1 pt. General correctness/design/efficiency issues
1 pt. conditionals and loops
1 pt. Parameters, variables, and scoping
1 pt. Good correct use of arrays
1 pt. Good use of private methods
2 pts. Good use of strings
Correctness (5 pts total)
1 pt. Connecting to mail server and disconnecting
1 pt. Downloading mail and saving it
1 pt. Extracting from and subject headers
1 pt. Adding and removing filters
1 pt. Applying filters to downloaded mail

SpamFilter GUI components

To assist you in creating your design, here is a list of instance variables in the starter file for SpamFilter corresponding to the GUI components in the user interface:
    // GUI components dealing with the list of filters.
    private JButton addFilterButton;	// Button to add term to filter
    private JButton removeFilterButton;	// Button to remove term from filter
    private JTextField filterField;		// Where user enters new filter or one to remove
    private JTextArea filterArea;		// Where all filters are displayed
    
    // GUI components dealing with connecting to a mail account.
    private JButton connectButton;	// button to connect to mail account
    private JTextField user;		// used to enter account identifer
    private JPasswordField pass;	// used to enter account password
    private JComboBox servers;		// pop-up menu to choose mail server

    // JComboBox to allow the user to decide whether to show the headers from the
    // good mail or the headers from the spam mail.
    private JComboBox goodOrSpam;
    
    // Larege text area where headers of good mail or spam are shown.
    private JTextArea mailArea;


Computer Science 051
Department of Math & Computer Science
Pomona College