    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 acceptable header for an email message. To construct more complicated headers you should refer to RFC 5322.
    026 * When the Java Mail API is finalized, you will be able to use it to compose fully compliant Internet text messages.
    027 * <p>
    028 * The main purpose of the class is to faciliatate the mail sending process, by relieving the programmer from having to explicitly format a simple message
    029 * header. For example:
    030 *
    031 * <pre>
    032 * writer = client.sendMessageData();
    033 * if(writer == null) // failure
    034 *   return false;
    035 * header =
    036 *    new SimpleSMTPHeader("foobar@foo.com", "foo@bar.com" "Just testing");
    037 * header.addCC("bar@foo.com");
    038 * header.addHeaderField("Organization", "Foobar, Inc.");
    039 * writer.write(header.toString());
    040 * writer.write("This is just a test");
    041 * writer.close();
    042 * if(!client.completePendingCommand()) // failure
    043 *   return false;
    044 * </pre>
    045 *
    046 * @see SMTPClient
    047 */
    048
    049public class SimpleSMTPHeader {
    050    private final String subject;
    051    private final String from;
    052    private final String to;
    053    private final StringBuffer headerFields;
    054    private boolean hasHeaderDate;
    055    private StringBuffer cc;
    056
    057    /**
    058     * Creates a new SimpleSMTPHeader instance initialized with the given from, to, and subject header field values.
    059     * <p>
    060     *
    061     * @param from    The value of the <code>From:</code> header field. This should be the sender's email address. Must not be null.
    062     * @param to      The value of the <code>To:</code> header field. This should be the recipient's email address. May be null
    063     * @param subject The value of the <code>Subject:</code> header field. This should be the subject of the message. May be null
    064     */
    065    public SimpleSMTPHeader(final String from, final String to, final String subject) {
    066        if (from == null) {
    067            throw new IllegalArgumentException("From cannot be null");
    068        }
    069        this.to = to;
    070        this.from = from;
    071        this.subject = subject;
    072        this.headerFields = new StringBuffer();
    073        this.cc = null;
    074    }
    075
    076    /**
    077     * Add an email address to the CC (carbon copy or courtesy copy) list.
    078     * <p>
    079     *
    080     * @param address The email address to add to the CC list.
    081     */
    082    public void addCC(final String address) {
    083        if (cc == null) {
    084            cc = new StringBuffer();
    085        } else {
    086            cc.append(", ");
    087        }
    088
    089        cc.append(address);
    090    }
    091
    092    /**
    093     * Adds an arbitrary header field with the given value to the article header. These headers will be written before the From, To, Subject, and Cc fields when
    094     * the SimpleSMTPHeader is convertered to a string. An example use would be:
    095     *
    096     * <pre>
    097     * header.addHeaderField("Organization", "Foobar, Inc.");
    098     * </pre>
    099     * <p>
    100     *
    101     * @param headerField The header field to add, not including the colon.
    102     * @param value       The value of the added header field.
    103     */
    104    public void addHeaderField(final String headerField, final String value) {
    105        if (!hasHeaderDate && "Date".equals(headerField)) {
    106            hasHeaderDate = true;
    107        }
    108        headerFields.append(headerField);
    109        headerFields.append(": ");
    110        headerFields.append(value);
    111        headerFields.append('\n');
    112    }
    113
    114    /**
    115     * Converts the SimpleSMTPHeader to a properly formatted header in the form of a String, including the blank line used to separate the header from the
    116     * article body. The header fields CC and Subject are only included when they are non-null.
    117     * <p>
    118     *
    119     * @return The message header in the form of a String.
    120     */
    121    @Override
    122    public String toString() {
    123        final StringBuilder header = new StringBuilder();
    124
    125        final String pattern = "EEE, dd MMM yyyy HH:mm:ss Z"; // Fri, 21 Nov 1997 09:55:06 -0600
    126        final SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.ENGLISH);
    127
    128        if (!hasHeaderDate) {
    129            addHeaderField("Date", format.format(new Date()));
    130        }
    131        if (headerFields.length() > 0) {
    132            header.append(headerFields.toString());
    133        }
    134
    135        header.append("From: ").append(from).append("\n");
    136
    137        if (to != null) {
    138            header.append("To: ").append(to).append("\n");
    139        }
    140
    141        if (cc != null) {
    142            header.append("Cc: ").append(cc.toString()).append("\n");
    143        }
    144
    145        if (subject != null) {
    146            header.append("Subject: ").append(subject).append("\n");
    147        }
    148
    149        header.append('\n'); // end of headers; body follows
    150
    151        return header.toString();
    152    }
    153}