Design by Interface
by Robb Shecter

Listing One
// file: EmailMessage.java
package net;
import java.io.IOException;
/** A a simple email message class. It allows email messages to be sent 
 * easily from Java. Here's how it is used:
 * <pre>
 *  EmailMessage message = Mail.newMessage();
 *  message.setSender("santa@north.pole");
 *  message.addRecipient("shecter@lion-ag.de");
 *  message.setSubject("Have you been naughty or nice?");
 *  message.setContent("Just checking...");
 *  message.send();
 * </pre>
 * The order of the various set()'s and add()'s is not important.  Just
 * make send() the last operation.  Multiple recipients can be specified by
 * calling addRecipient() or addCC() multiple times.
 * @see Mail
 **/
public interface EmailMessage {
    /** Specify the <code>From:</code> header of the message. **/
    public void setSender(String address);

    /** Specify a <code>To:</code> header of the message.  This can be
     *  invoked more than once for messages with multiple recipients.
     **/
    public void addRecipient(String address);

    /** Specify a <code>Cc:</code> header of the message.  This can be
     *  invoked more than once for messages with multiple recipients. **/
    public void addCC(String address);

    /** Specify the <code>Subject:</code> header of the message. **/
    public void setSubject(String subject);

    /** Specify the actual text of the message. **/
    public void setContent(String content);

    /** Connect to the mail server and deliver the message.
     * @exception  IOException  can be thrown for many, many reasons. **/
    public void send() throws IOException;
}

Listing Two
// file: OROEmailAdapter.java
package net;

import java.io.*;
import java.util.*;
import com.oroinc.net.smtp.*;

/** An EmailMessage implementation that uses the ORO tcp/ip toolkit.  **/
class OROEmailAdapter implements EmailMessage {
    private static final boolean DEBUG = false;
    private Vector recipients  = new Vector();
    private Vector ccs         = new Vector();
    private String subject     = "";
    private String content     = "";
    private String server      = "";
    private String sender      = null;

    public OROEmailAdapter(String server) {
    this.server = server;
    }
    public void setSender(String address) {
    sender = address;
    }
    public void addRecipient(String address) {
    recipients.addElement(address);
    }
    public void addCC(String address) {
    ccs.addElement(address);
    }
    public void setSubject(String subject) {
    this.subject = subject;
    }
    public void setContent(String content) {
    this.content = content;
    }
    public void send() throws IOException {
    SMTPClient client = new SMTPClient();
    client.connect(server);
    debug(client.getReplyString());
    if (! SMTPReply.isPositiveCompletion(client.getReplyCode())) {
        throw new IOException("SMTP server refused connection");
    }
    client.login();
    debug(client.getReplyString());
    
    SimpleSMTPHeader header = makeHeader(client);
    Writer writer = client.sendMessageData();
    debug(client.getReplyString());
    if (writer == null) {
        throw new IOException("Could not send message data");
    }
    writer.write(header.toString());
    writer.close();
    if (! client.completePendingCommand()) {    // failure
        throw new IOException("Could not complete pending command");
    }
    client.logout();
    debug(client.getReplyString());
    client.disconnect();
    }
    /** Create the header for the message. **/
    private SimpleSMTPHeader makeHeader(SMTPClient client) throws IOException {
    // Prepare the 'From' header.
    String from = sender.toString();
    if (from == null) { from = ""; };
    client.setSender(from);

    // Prepare the 'To' header.
    int toCount = 0;
    String to = "";
    Enumeration addrs = recipients.elements();
    while (addrs.hasMoreElements()) {
        toCount++;
        if (toCount > 1) {
        to += ", ";
        }
        String addr = (String)addrs.nextElement();
        debug("adding recipient: "+addr);
        client.addRecipient(addr);
        debug(client.getReplyString());
        to += addr;
    }
    // Now we can instantiate the header.
    SimpleSMTPHeader header = new SimpleSMTPHeader(from, to, subject);
    
    // Add in cc's, if any.
    Enumeration carbonCopies = ccs.elements();
    while (carbonCopies.hasMoreElements()) {
        String addr = (String)carbonCopies.nextElement();
        client.addRecipient(addr);
        debug(client.getReplyString());
        header.addCC(addr);
    }
    return header;
    }
    /** Simple debuging output **/
    private void debug(String s) {
    if (DEBUG)
        System.out.println("debug in OROEmailMessage: "+s);
    }
}

Listing Three
// file: Mail.java
package net;
/** E-mail system.  Use this class to construct new e-mail messages.
 * <pre>
 *  EmailMessage mesg = Mail.newMessage();
 * </pre>
 * See the documentation for EmailMessage for details on how to manipulate
 * and send it.<p>
 * @see     EmailMessage
 **/
public class Mail {
    /** Create a new email message that uses the default LION SMTP server. **/
    public static EmailMessage newMessage() {
    return new OROEmailAdapter("mail.lion-ag.de");
    }
}

Listing Four
// file: MailTest.java
package net;
/** A short program that sends test e-mail messages. **/
public class MailTest {
    public static void main(String[] argv) {
    /* Check command line arguments */
    if (argv.length != 2) {
        System.out.println("Usage: MailTest <from> <to>");
        System.exit(0);
    }
    /* Create and send a test message */
    try {
        EmailMessage mesg = Mail.newMessage();
        mesg.setSender( argv[0] );
        mesg.addRecipient( argv[1] );
        mesg.setSubject("Hello from Java!");
        mesg.setContent("Hi! \n\n This is a test message.");
        mesg.send();
        System.out.println("Message was successfully sent.");
    }
    catch (Exception e) {
        System.out.println("An exception occurred: " + e);
        System.exit(1);
    }
  }
}


1


