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