001: /*
002: * Email.java
003: *
004: * Version: $Revision: 2198 $
005: *
006: * Date: $Date: 2007-09-17 10:39:36 -0500 (Mon, 17 Sep 2007) $
007: *
008: * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
009: * Institute of Technology. All rights reserved.
010: *
011: * Redistribution and use in source and binary forms, with or without
012: * modification, are permitted provided that the following conditions are
013: * met:
014: *
015: * - Redistributions of source code must retain the above copyright
016: * notice, this list of conditions and the following disclaimer.
017: *
018: * - Redistributions in binary form must reproduce the above copyright
019: * notice, this list of conditions and the following disclaimer in the
020: * documentation and/or other materials provided with the distribution.
021: *
022: * - Neither the name of the Hewlett-Packard Company nor the name of the
023: * Massachusetts Institute of Technology nor the names of their
024: * contributors may be used to endorse or promote products derived from
025: * this software without specific prior written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
028: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
029: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
030: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
031: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
032: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
033: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
034: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
035: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
036: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
037: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
038: * DAMAGE.
039: */
040: package org.dspace.core;
041:
042: import java.io.File;
043: import java.text.MessageFormat;
044: import java.util.ArrayList;
045: import java.util.Date;
046: import java.util.Iterator;
047: import java.util.List;
048: import java.util.Properties;
049:
050: import javax.activation.DataHandler;
051: import javax.activation.FileDataSource;
052: import javax.mail.Address;
053: import javax.mail.Authenticator;
054: import javax.mail.BodyPart;
055: import javax.mail.Message;
056: import javax.mail.MessagingException;
057: import javax.mail.Multipart;
058: import javax.mail.PasswordAuthentication;
059: import javax.mail.Session;
060: import javax.mail.Transport;
061: import javax.mail.internet.InternetAddress;
062: import javax.mail.internet.MimeBodyPart;
063: import javax.mail.internet.MimeMessage;
064: import javax.mail.internet.MimeMultipart;
065:
066: /**
067: * Class representing an e-mail message, also used to send e-mails.
068: * <P>
069: * Typical use:
070: * <P>
071: * <code>Email email = ConfigurationManager.getEmail(name);</code><br>
072: * <code>email.addRecipient("foo@bar.com");</code><br>
073: * <code>email.addArgument("John");</code><br>
074: * <code>email.addArgument("On the Testing of DSpace");</code><br>
075: * <code>email.send();</code><br>
076: * <P>
077: * <code>name</code> is the name of an email template in
078: * <code>dspace-dir/config/emails/</code> (which also includes the subject.)
079: * <code>arg0</code> and <code>arg1</code> are arguments to fill out the
080: * message with.
081: * <P>
082: * Emails are formatted using <code>java.text.MessageFormat.</code>
083: * Additionally, comment lines (starting with '#') are stripped, and if a line
084: * starts with "Subject:" the text on the right of the colon is used for the
085: * subject line. For example:
086: * <P>
087: *
088: * <pre>
089: *
090: * # This is a comment line which is stripped
091: * #
092: * # Parameters: {0} is a person's name
093: * # {1} is the name of a submission
094: * #
095: * Subject: Example e-mail
096: *
097: * Dear {0},
098: *
099: * Thank you for sending us your submission "{1}".
100: *
101: * </pre>
102: *
103: * <P>
104: * If the example code above was used to send this mail, the resulting mail
105: * would have the subject <code>Example e-mail</code> and the body would be:
106: * <P>
107: *
108: * <pre>
109: *
110: *
111: * Dear John,
112: *
113: * Thank you for sending us your submission "On the Testing of DSpace".
114: *
115: * </pre>
116: *
117: * <P>
118: * Note that parameters like <code>{0}</code> cannot be placed in the subject
119: * of the e-mail; they won't get filled out.
120: *
121: *
122: * @author Robert Tansley
123: * @author Jim Downing - added attachment handling code
124: * @version $Revision: 2198 $
125: */
126: public class Email {
127: /*
128: * Implementation note: It might be necessary to add a quick utility method
129: * like "send(to, subject, message)". We'll see how far we get without it -
130: * having all emails as templates in the config allows customisation and
131: * internationalisation.
132: *
133: * Note that everything is stored and the run in send() so that only send()
134: * throws a MessagingException.
135: */
136:
137: /** The content of the message */
138: private String content;
139:
140: /** The subject of the message */
141: private String subject;
142:
143: /** The arguments to fill out */
144: private List arguments;
145:
146: /** The recipients */
147: private List recipients;
148:
149: /** Reply to field, if any */
150: private String replyTo;
151:
152: private List attachments;
153:
154: /** The character set this message will be sent in */
155: private String charset;
156:
157: /**
158: * Create a new email message.
159: */
160: Email() {
161: arguments = new ArrayList(50);
162: recipients = new ArrayList(50);
163: attachments = new ArrayList(10);
164: subject = "";
165: content = "";
166: replyTo = null;
167: charset = null;
168: }
169:
170: /**
171: * Add a recipient
172: *
173: * @param email
174: * the recipient's email address
175: */
176: public void addRecipient(String email) {
177: recipients.add(email);
178: }
179:
180: /**
181: * Set the content of the message. Setting this "resets" the message
182: * formatting -<code>addArgument</code> will start. Comments and any
183: * "Subject:" line must be stripped.
184: *
185: * @param cnt
186: * the content of the message
187: */
188: void setContent(String cnt) {
189: content = cnt;
190: arguments = new ArrayList();
191: }
192:
193: /**
194: * Set the subject of the message
195: *
196: * @param s
197: * the subject of the message
198: */
199: void setSubject(String s) {
200: subject = s;
201: }
202:
203: /**
204: * Set the reply-to email address
205: *
206: * @param email
207: * the reply-to email address
208: */
209: public void setReplyTo(String email) {
210: replyTo = email;
211: }
212:
213: /**
214: * Fill out the next argument in the template
215: *
216: * @param arg
217: * the value for the next argument
218: */
219: public void addArgument(Object arg) {
220: arguments.add(arg);
221: }
222:
223: public void addAttachment(File f, String name) {
224: attachments.add(new FileAttachment(f, name));
225: }
226:
227: public void setCharset(String cs) {
228: charset = cs;
229: }
230:
231: /**
232: * "Reset" the message. Clears the arguments and recipients, but leaves the
233: * subject and content intact.
234: */
235: public void reset() {
236: arguments = new ArrayList(50);
237: recipients = new ArrayList(50);
238: attachments = new ArrayList(10);
239: replyTo = null;
240: charset = null;
241: }
242:
243: /**
244: * Sends the email.
245: *
246: * @throws MessagingException
247: * if there was a problem sending the mail.
248: */
249: public void send() throws MessagingException {
250: // Get the mail configuration properties
251: String server = ConfigurationManager.getProperty("mail.server");
252: String from = ConfigurationManager
253: .getProperty("mail.from.address");
254:
255: // Set up properties for mail session
256: Properties props = System.getProperties();
257: props.put("mail.smtp.host", server);
258:
259: // Set the port number for the mail server
260: String portNo = ConfigurationManager
261: .getProperty("mail.server.port");
262: if (portNo == null) {
263: portNo = "25";
264: }
265: props.put("mail.smtp.port", portNo.trim());
266:
267: // If no character set specified, attempt to retrieve a default
268: if (charset == null) {
269: charset = ConfigurationManager.getProperty("mail.charset");
270: }
271:
272: // Get session
273: Session session;
274:
275: // Get the SMTP server authentication information
276: String username = ConfigurationManager
277: .getProperty("mail.server.username");
278: String password = ConfigurationManager
279: .getProperty("mail.server.password");
280:
281: if (username != null) {
282: props.put("mail.smtp.auth", "true");
283: SMTPAuthenticator smtpAuthenticator = new SMTPAuthenticator(
284: username, password);
285: session = Session.getDefaultInstance(props,
286: smtpAuthenticator);
287: } else {
288: session = Session.getDefaultInstance(props);
289: }
290:
291: // Create message
292: MimeMessage message = new MimeMessage(session);
293:
294: // Set the recipients of the message
295: Iterator i = recipients.iterator();
296:
297: while (i.hasNext()) {
298: message.addRecipient(Message.RecipientType.TO,
299: new InternetAddress((String) i.next()));
300: }
301:
302: // Format the mail message
303: Object[] args = arguments.toArray();
304: String fullMessage = MessageFormat.format(content, args);
305: Date date = new Date();
306:
307: message.setSentDate(date);
308: message.setFrom(new InternetAddress(from));
309: message.setSubject(subject);
310: if (attachments.isEmpty()) {
311: // If a character set has been specified, or a default exists
312: if (charset != null) {
313: message.setText(fullMessage, charset);
314: } else {
315: message.setText(fullMessage);
316: }
317: } else {
318: Multipart multipart = new MimeMultipart();
319: // create the first part of the email
320: BodyPart messageBodyPart = new MimeBodyPart();
321: messageBodyPart.setText(fullMessage);
322: multipart.addBodyPart(messageBodyPart);
323:
324: for (Iterator iter = attachments.iterator(); iter.hasNext();) {
325: FileAttachment f = (FileAttachment) iter.next();
326: // add the file
327: messageBodyPart = new MimeBodyPart();
328: messageBodyPart.setDataHandler(new DataHandler(
329: new FileDataSource(f.file)));
330: messageBodyPart.setFileName(f.name);
331: multipart.addBodyPart(messageBodyPart);
332: }
333: message.setContent(multipart);
334: }
335:
336: if (replyTo != null) {
337: Address[] replyToAddr = new Address[1];
338: replyToAddr[0] = new InternetAddress(replyTo);
339: message.setReplyTo(replyToAddr);
340: }
341:
342: Transport.send(message);
343: }
344:
345: /**
346: * Utility struct class for handling file attachments.
347: *
348: * @author ojd20
349: *
350: */
351: private class FileAttachment {
352: public FileAttachment(File f, String n) {
353: this .file = f;
354: this .name = n;
355: }
356:
357: File file;
358:
359: String name;
360: }
361:
362: /**
363: * Inner Class for SMTP authentication information
364: */
365: private class SMTPAuthenticator extends Authenticator {
366: // User name
367: private String name;
368:
369: // Password
370: private String password;
371:
372: public SMTPAuthenticator(String n, String p) {
373: name = n;
374: password = p;
375: }
376:
377: protected PasswordAuthentication getPasswordAuthentication() {
378: return new PasswordAuthentication(name, password);
379: }
380: }
381: }
|