001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net.smtp;
019
020import java.text.SimpleDateFormat;
021import java.util.Date;
022import java.util.Locale;
023
024/**
025 * This class is used to construct a bare minimum
026 * acceptable header for an email message.  To construct more
027 * complicated headers you should refer to RFC 5322.  When the
028 * Java Mail API is finalized, you will be
029 * able to use it to compose fully compliant Internet text messages.
030 * <p>
031 * The main purpose of the class is to faciliatate the mail sending
032 * process, by relieving the programmer from having to explicitly format
033 * a simple message header.  For example:
034 * <pre>
035 * writer = client.sendMessageData();
036 * if(writer == null) // failure
037 *   return false;
038 * header =
039 *    new SimpleSMTPHeader("foobar@foo.com", "foo@bar.com" "Just testing");
040 * header.addCC("bar@foo.com");
041 * header.addHeaderField("Organization", "Foobar, Inc.");
042 * writer.write(header.toString());
043 * writer.write("This is just a test");
044 * writer.close();
045 * if(!client.completePendingCommand()) // failure
046 *   return false;
047 * </pre>
048 *
049 * @see SMTPClient
050 */
051
052public class SimpleSMTPHeader
053{
054    private final String subject;
055    private final String from;
056    private final String to;
057    private final StringBuffer headerFields;
058    private boolean hasHeaderDate;
059    private StringBuffer cc;
060
061    /**
062     * Creates a new SimpleSMTPHeader instance initialized with the given
063     * from, to, and subject header field values.
064     * <p>
065     * @param from  The value of the <code>From:</code> header field.  This
066     *              should be the sender's email address.
067     *              Must not be null.
068     * @param to    The value of the <code>To:</code> header field.  This
069     *              should be the recipient's email address.
070     *              May be null
071     * @param subject  The value of the <code>Subject:</code> header field.
072     *              This should be the subject of the message.
073     *              May be null
074     */
075    public SimpleSMTPHeader(final String from, final String to, final String subject)
076    {
077        if (from == null) {
078            throw new IllegalArgumentException("From cannot be null");
079        }
080        this.to = to;
081        this.from = from;
082        this.subject = subject;
083        this.headerFields = new StringBuffer();
084        this.cc = null;
085    }
086
087    /**
088     * Adds an arbitrary header field with the given value to the article
089     * header.  These headers will be written before the From, To, Subject, and
090     * Cc fields when the SimpleSMTPHeader is convertered to a string.
091     * An example use would be:
092     * <pre>
093     * header.addHeaderField("Organization", "Foobar, Inc.");
094     * </pre>
095     * <p>
096     * @param headerField  The header field to add, not including the colon.
097     * @param value  The value of the added header field.
098     */
099    public void addHeaderField(final String headerField, final String value)
100    {
101        if (!hasHeaderDate && "Date".equals(headerField)) {
102            hasHeaderDate = true;
103        }
104        headerFields.append(headerField);
105        headerFields.append(": ");
106        headerFields.append(value);
107        headerFields.append('\n');
108    }
109
110
111    /**
112     * Add an email address to the CC (carbon copy or courtesy copy) list.
113     * <p>
114     * @param address The email address to add to the CC list.
115     */
116    public void addCC(final String address)
117    {
118        if (cc == null) {
119            cc = new StringBuffer();
120        } else {
121            cc.append(", ");
122        }
123
124        cc.append(address);
125    }
126
127
128    /**
129     * Converts the SimpleSMTPHeader to a properly formatted header in
130     * the form of a String, including the blank line used to separate
131     * the header from the article body.  The header fields CC and Subject
132     * are only included when they are non-null.
133     * <p>
134     * @return The message header in the form of a String.
135     */
136    @Override
137    public String toString()
138    {
139        final StringBuilder header = new StringBuilder();
140
141        final String pattern = "EEE, dd MMM yyyy HH:mm:ss Z"; // Fri, 21 Nov 1997 09:55:06 -0600
142        final SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
143
144        if (!hasHeaderDate) {
145            addHeaderField("Date", format.format(new Date()));
146        }
147        if (headerFields.length() > 0) {
148            header.append(headerFields.toString());
149        }
150
151        header.append("From: ").append(from).append("\n");
152
153        if (to != null) {
154            header.append("To: ").append(to).append("\n");
155        }
156
157        if (cc != null)
158        {
159            header.append("Cc: ").append(cc.toString()).append("\n");
160        }
161
162        if (subject != null)
163        {
164            header.append("Subject: ").append(subject).append("\n");
165        }
166
167        header.append('\n'); // end of headers; body follows
168
169        return header.toString();
170    }
171}
172
173
174