001 /**
002 * Jetrix TetriNET Server
003 * Copyright (C) 2009 Emmanuel Bourg
004 *
005 * This program is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU General Public License
007 * as published by the Free Software Foundation; either version 2
008 * of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program; if not, write to the Free Software
017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
018 */
019
020 package net.jetrix.mail;
021
022 import java.io.File;
023 import java.util.Date;
024 import java.util.HashSet;
025 import java.util.Set;
026 import javax.activation.DataHandler;
027 import javax.activation.DataSource;
028 import javax.activation.FileDataSource;
029 import javax.mail.Address;
030 import javax.mail.Message;
031 import javax.mail.MessagingException;
032 import javax.mail.Multipart;
033 import javax.mail.Session;
034 import javax.mail.Transport;
035 import javax.mail.internet.AddressException;
036 import javax.mail.internet.InternetAddress;
037 import javax.mail.internet.MimeBodyPart;
038 import javax.mail.internet.MimeMessage;
039 import javax.mail.internet.MimeMultipart;
040
041 /**
042 * A simple mail message. This class intends to abstract the complexity
043 * of the JavaMail API for simple usages. It relies on the MailSessionManager
044 * to provide a valid mail session.
045 *
046 * @author Emmanuel Bourg
047 * @version $Revision: 800 $, $Date: 2009-02-18 19:26:28 +0100 (Wed, 18 Feb 2009) $
048 * @since 0.3
049 */
050 public class MailMessage
051 {
052 private static final String DEFAULT_CHARSET = "iso-8859-1";
053
054 private CharSequence subject;
055 private CharSequence body;
056
057 private InternetAddress from;
058
059 private Set<InternetAddress> recipients = new HashSet<InternetAddress>();
060 private Set<InternetAddress> recipientsCC = new HashSet<InternetAddress>();
061 private Set<InternetAddress> recipientsBCC = new HashSet<InternetAddress>();
062
063 private Set<DataSource> attachments = new HashSet<DataSource>();
064
065 public MailMessage()
066 {
067 }
068
069 public void setSubject(CharSequence subject)
070 {
071 this.subject = subject;
072 }
073
074 public void setBody(CharSequence body)
075 {
076 this.body = body;
077 }
078
079 public void setFrom(InternetAddress from)
080 {
081 this.from = from;
082 }
083
084 public void setFrom(String from) throws AddressException
085 {
086 this.from = new InternetAddress(from, false);
087 }
088
089 public void addRecipient(String address) throws AddressException
090 {
091 recipients.add(new InternetAddress(address));
092 }
093
094 public void addRecipientCC(String address) throws AddressException
095 {
096 recipientsCC.add(new InternetAddress(address));
097 }
098
099 public void addRecipientBCC(String address) throws AddressException
100 {
101 recipientsBCC.add(new InternetAddress(address));
102 }
103
104 public void addRecipient(InternetAddress address)
105 {
106 recipients.add(address);
107 }
108
109 public void addRecipientCC(InternetAddress address)
110 {
111 recipientsCC.add(address);
112 }
113
114 public void addRecipientBCC(InternetAddress address)
115 {
116 recipientsBCC.add(address);
117 }
118
119 public void addAttachment(File file)
120 {
121 attachments.add(new FileDataSource(file));
122 }
123
124 public void addAttachment(DataSource datasource)
125 {
126 attachments.add(datasource);
127 }
128
129 /**
130 * Send the message, and if requested, asynchronously in a separate thread.
131 *
132 * @param asynchronous send the message in a separate thread
133 */
134 public void send(boolean asynchronous) throws MessagingException
135 {
136 if (!asynchronous)
137 {
138 send();
139 }
140 else
141 {
142 new Thread("MailMessage.send()")
143 {
144 public void run()
145 {
146 try
147 {
148 send();
149 }
150 catch (MessagingException e)
151 {
152 throw new RuntimeException("An error occured when sending the mail", e);
153 }
154 }
155 }.start();
156 }
157 }
158
159 /**
160 * Send the message.
161 */
162 public void send() throws MessagingException
163 {
164 Session session = MailSessionManager.getInstance().getSession();
165
166 // build the message
167 MimeMessage message = new MimeMessage(session);
168 message.setSubject(subject.toString(), DEFAULT_CHARSET);
169 message.setFrom(from);
170
171 message.addRecipients(Message.RecipientType.TO, recipients.toArray(new Address[recipients.size()]));
172 message.addRecipients(Message.RecipientType.CC, recipientsCC.toArray(new Address[recipientsCC.size()]));
173 message.addRecipients(Message.RecipientType.BCC, recipientsBCC.toArray(new Address[recipientsBCC.size()]));
174
175 message.setHeader("Content-Transfer-Encoding", "8bit");
176 message.setSentDate(new Date());
177
178 MimeBodyPart part1 = new MimeBodyPart();
179 if (body.toString().toLowerCase().trim().startsWith("<html") || body.toString().toLowerCase().trim().startsWith("<!doctype html"))
180 {
181 part1.setContent(body.toString(), "text/html; charset=" + DEFAULT_CHARSET);
182 }
183 else
184 {
185 part1.setText(body.toString(), DEFAULT_CHARSET);
186 }
187 part1.setHeader("Content-Transfer-Encoding", "8bit");
188
189 Multipart content = new MimeMultipart();
190 content.addBodyPart(part1);
191
192 // add attachments
193 for (DataSource attachment : attachments)
194 {
195 MimeBodyPart part2 = new MimeBodyPart();
196 part2.setDataHandler(new DataHandler(attachment));
197 part2.setFileName(attachment.getName());
198
199 content.addBodyPart(part2);
200 }
201
202 message.setContent(content);
203 message.saveChanges();
204
205 // send the message
206 Transport transport = session.getTransport();
207
208 try
209 {
210 transport.connect();
211 transport.sendMessage(message, message.getAllRecipients());
212 }
213 finally
214 {
215 if (transport.isConnected())
216 {
217 transport.close();
218 }
219 }
220 }
221 }