Code for EmailClient Lab

This page contains the code for all the other classes in the EmailClient lab: EmailClient.java and EmailMessage.java.


EmailClient.java

/*************************************
 * Filename:  EmailClient.java
 *************************************/

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;

public class EmailClient extends Frame {
	/* The stuff for the GUI. */
	private Button btSend = new Button("Send");
	private Button btClear = new Button("Clear");
	private Button btQuit = new Button("Quit");
	private Label serverLabel = new Label("Local SMTP server:");
	private TextField serverField = new TextField("35.246.110.174", 40);
	private Label serverPortLabel = new Label("Port number of SMTP server:");
	private TextField serverPortField = new TextField("1025", 30);
	private Label fromLabel = new Label("From:");
	private TextField fromField = new TextField("", 40);
	private Label toLabel = new Label("To:"); 
	private TextField toField = new TextField("", 40);
	private Label subjectLabel = new Label("Subject:");
	private TextField subjectField = new TextField("", 40);
	private Label messageLabel = new Label("Message:");
	private TextArea messageText = new TextArea(30, 80);
	private Label urlLabel = new Label("HTTP://");
	private TextField urlField = new TextField("comp211.gairing.com/test.txt", 40);
	private Button btGet = new Button("Get");

    /**
     * Create a new EmailClient window with fields for entering all
     * the relevant information (From, To, Subject, and message).
     */
    public EmailClient() {
		super("Java Emailclient");
	
	/* Create panels for holding the fields. To make it look nice,
	   create an extra panel for holding all the child panels. */
	Panel serverPanel = new Panel(new BorderLayout());
	Panel serverPortPanel = new Panel(new BorderLayout());
	Panel fromPanel = new Panel(new BorderLayout());
	Panel toPanel = new Panel(new BorderLayout());
	Panel subjectPanel = new Panel(new BorderLayout());
	Panel messagePanel = new Panel(new BorderLayout());
	serverPanel.add(serverLabel, BorderLayout.WEST);
	serverPanel.add(serverField, BorderLayout.CENTER);
	serverPortPanel.add(serverPortLabel, BorderLayout.WEST);
	serverPortPanel.add(serverPortField, BorderLayout.CENTER);
	fromPanel.add(fromLabel, BorderLayout.WEST);
	fromPanel.add(fromField, BorderLayout.CENTER);
	toPanel.add(toLabel, BorderLayout.WEST);
	toPanel.add(toField, BorderLayout.CENTER);
	subjectPanel.add(subjectLabel, BorderLayout.WEST);
	subjectPanel.add(subjectField, BorderLayout.CENTER);
	messagePanel.add(messageLabel, BorderLayout.NORTH);	
	messagePanel.add(messageText, BorderLayout.CENTER);
	Panel fieldPanel = new Panel(new GridLayout(0, 1));
	fieldPanel.add(serverPanel);
	fieldPanel.add(serverPortPanel);
	fieldPanel.add(fromPanel);
	fieldPanel.add(toPanel);
	fieldPanel.add(subjectPanel);
		
	/* Create a panel for the URL field and add listener to the GET 
	   button. */
	Panel urlPanel = new Panel(new BorderLayout());
	urlPanel.add(urlLabel, BorderLayout.WEST);
	urlPanel.add(urlField, BorderLayout.CENTER);
	urlPanel.add(btGet, BorderLayout.EAST);
	fieldPanel.add(urlPanel);
	btGet.addActionListener(new GetListener());
		

	/* Create a panel for the buttons and add listeners to the
	   buttons. */
	Panel buttonPanel = new Panel(new GridLayout(1, 0));
	btSend.addActionListener(new SendListener());
	btClear.addActionListener(new ClearListener());
	btQuit.addActionListener(new QuitListener());
	buttonPanel.add(btSend);
	buttonPanel.add(btClear);
	buttonPanel.add(btQuit);
	
	/* Add, pack, and show. */
	add(fieldPanel, BorderLayout.NORTH);
	add(messagePanel, BorderLayout.CENTER);
	add(buttonPanel, BorderLayout.SOUTH);
	pack();
	setVisible(true);
    }

    static public void main(String argv[]) {
	new EmailClient();
    }

    /* Handler for the Send-button. */
    class SendListener implements ActionListener {
	public void actionPerformed(ActionEvent event) {
	    System.out.println("Sending mail");
	    
	    /* Check that we have the local mailserver */
	    if ((serverField.getText()).equals("")) {
			System.out.println("Need name of SMTP server!");
		return;
	    }

	    /* Check that we have a port number */
	    if ((serverPortField.getText()).equals("")) {
			System.out.println("Need Port number of  SMTP server!");
		return;
	    }


	    /* Check that we have the sender and recipient. */
	    if((fromField.getText()).equals("")) {
			System.out.println("Need sender!");
		return;
	    }
	    if((toField.getText()).equals("")) {
			System.out.println("Need recipient!");
		return;
	    }

	    /* Create the message */
	    EmailMessage mailMessage;
        try {
	    mailMessage = new EmailMessage(fromField.getText(), 
					      toField.getText(), 
					      subjectField.getText(), 
					      messageText.getText(),
                                              serverField.getText(),
                                              Integer.parseInt(serverPortField.getText()));
        } catch (UnknownHostException e) {
    		/* If there is an error, do not go further */
    		return;
    	    }
        
	    /* Check that the message is valid, i.e., sender and
	       recipient addresses look ok. */
	    if(!mailMessage.isValid()) {
		return;
	    }

	    try {
			SMTPInteraction connection = new SMTPInteraction(mailMessage);
			connection.send(mailMessage);
			connection.close();
	    } catch (IOException error) {
		System.out.println("Sending failed: " + error);
		return;
	    }
	    System.out.println("Email sent succesfully!");
	}
    }

    /* Get URL if specified. */
    class GetListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			
			String receivedText;

			/* Check if URL field is empty. */
			if((urlField.getText()).equals("")) {
				System.out.println("Need URL!");
				return;
			}			
			/* Pass string from URL field to HTTPGet (trimmed);
			   returned string is either requested object 
			   or some error message. */
/*********************************************
 * Uncomment this for part 2
 ********************************************* 
 			HTTPInteraction request = new HTTPInteraction(urlField.getText().trim());
			
			// Send http request. Returned String holds object 
			try {
				receivedText=request.send();
			}
			catch (IOException error) {
				messageText.setText("Downloading File failed.\r\nIOException: " + error);
				return;
			}
			// Change message text 
			messageText.setText(receivedText);
*******************************************/
		}
    }
	
	
    /* Clear the fields on the GUI. */
    class ClearListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			System.out.println("Clearing fields");
			fromField.setText("");
			toField.setText("");
			subjectField.setText("");
			messageText.setText("");
		}
	}

    /* Quit. */
    class QuitListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			System.exit(0);
		}
    }
}


EmailMessage.java

/*************************************
 * Filename:  EmailMessage.java
 *************************************/

import java.util.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.*;

public class EmailMessage {
	/* SMTP-sender of the message (in this case, contents of From-header. */
	public String Sender;
	/* SMTP-recipient, or contents of To-header. */
	public String Recipient;
	/* Target MX-host */
	public String DestHost;
	private InetAddress DestAddr;

        public int DestHostPort;

	/* The headers and the body of the message. */
	public String Headers;
	public String Body;

	/* To make it look nicer */
	private static final String CRLF = "\r\n";

	/*
	 * Create the message object by inserting the required headers from RFC 822
	 * (From, To, Date).
	 */
	public EmailMessage(String from, String to, String subject, String text,
			String localServer, int localServerPort) throws UnknownHostException {
		/* Remove whitespace */
		Sender = from.trim();
		Recipient = to.trim();

		Headers = "From: " + Sender + CRLF;
		Headers += "To: " + Recipient + CRLF;
		Headers += "Subject: " + subject.trim() + CRLF;

		/*
		 * A close approximation of the required format. Unfortunately only GMT.
		 */
		SimpleDateFormat format = new SimpleDateFormat(
				"EEE, dd MMM yyyy HH:mm:ss 'GMT'");
		String dateString = format.format(new Date());
		Headers += "Date: " + dateString + CRLF;

		/*
		 * Get message. We must escape the message to make sure that there are
		 * no single periods on a line. This would mess up sending the mail.
		 */
		Body = escapeMessage(text);

		/*
		 * Take the name of the local mailserver and map it into an InetAddress
		 */
		DestHost = localServer;
		try {
			DestAddr = InetAddress.getByName(DestHost);
		} catch (UnknownHostException e) {
			System.out.println("Unknown host: " + DestHost);
			System.out.println(e);
			throw e;
		}
                DestHostPort = localServerPort;
	}

	/*
	 * Check whether the message is valid. In other words, check that both
	 * sender and recipient contain only one @-sign.
	 */
	public boolean isValid() {
		int fromat = Sender.indexOf('@');
		int toat = Recipient.indexOf('@');

		if (fromat < 1 || (Sender.length() - fromat) <= 1) {
			System.out.println("Sender address is invalid");
			return false;
		}
		if (toat < 1 || (Recipient.length() - toat) <= 1) {
			System.out.println("Recipient address is invalid");
			return false;
		}
		if (fromat != Sender.lastIndexOf('@')) {
			System.out.println("Sender address is invalid");
			return false;
		}
		if (toat != Recipient.lastIndexOf('@')) {
			System.out.println("Recipient address is invalid");
			return false;
		}
		return true;
	}

	/* For printing the message. */
	public String toString() {
		String res;

		res = "Sender: " + Sender + '\n';
		res += "Recipient: " + Recipient + '\n';
		res += "MX-host: " + DestHost + ", address: " + DestAddr + '\n';
		res += "Message:" + '\n';
		res += Headers + CRLF;
		res += Body;

		return res;
	}

	/*
	 * Escape the message by doubling all periods at the beginning of a line.
	 */
	private String escapeMessage(String body) {
		String escapedBody = "";
		String token;
		StringTokenizer parser = new StringTokenizer(body, "\n", true);

		while (parser.hasMoreTokens()) {
			token = parser.nextToken();
			if (token.startsWith(".")) {
				token = "." + token;
			}
			escapedBody += token;
		}
		return escapedBody;
	}
}