001: package ru.emdev.EmForge.email;
002:
003: import javax.mail.BodyPart;
004: import javax.mail.Message;
005: import javax.mail.MessagingException;
006: import javax.mail.Multipart;
007: import javax.mail.internet.InternetAddress;
008: import javax.mail.internet.MimeBodyPart;
009: import javax.mail.internet.MimeMessage;
010: import javax.mail.internet.MimeMultipart;
011:
012: import org.apache.commons.lang.StringUtils;
013: import org.apache.commons.logging.Log;
014: import org.apache.commons.logging.LogFactory;
015: import org.springframework.mail.MailException;
016: import org.springframework.mail.MailPreparationException;
017: import org.springframework.mail.javamail.JavaMailSenderImpl;
018:
019: import ru.emdev.EmForge.email.logger.EmailLogger;
020:
021: public class EmailSenderImpl extends JavaMailSenderImpl implements
022: EmailSender {
023: private final Log log = LogFactory.getLog(getClass());
024:
025: /** Currently, while we do not supports different customers in the system
026: * Customer Email usually used as "from" address will be specified in this bean
027: * This From Email is used only if from email is not specified in the email message
028: *
029: * Later, this bean will able get this information from current context
030: */
031: String fromMailAccount;
032:
033: /** This test mail account used for redirecting all emails to the
034: * specified mail account then application worked in test mode
035: * (instead of sending to specified users)
036: *
037: * Mail Sender works in test mode then testMailAccount is not null
038: *
039: */
040: private String testMailAccount;
041:
042: /** Email Logger is used for storing log information about all sent emails */
043: EmailLogger emailLogger;
044:
045: public void setFromMailAccount(String fromMailAccount) {
046: this .fromMailAccount = fromMailAccount;
047: }
048:
049: public void setTestMailAccount(String testMailAccount) {
050: this .testMailAccount = testMailAccount;
051: }
052:
053: public void setEmailLogger(EmailLogger emailLogger) {
054: this .emailLogger = emailLogger;
055: }
056:
057: // Spring Mail Sender Related Part
058: public void send(MimeMessage message) throws MailException {
059: preProcessEmail(message);
060: super .send(message);
061:
062: }
063:
064: /** Pre-Process email
065: * Is testMailAccount is specified - change mail address
066: * Outputs some additional logging messages
067: *
068: * @param message
069: */
070: private void preProcessEmail(MimeMessage message)
071: throws MailException {
072: try {
073: if (testMailAccount != null) {
074: log.debug("Email message redirected to the "
075: + testMailAccount);
076:
077: InternetAddress[] addresses = InternetAddress.parse(
078: testMailAccount, false);
079: message.setRecipients(Message.RecipientType.TO,
080: addresses);
081:
082: // clear cc and bcc
083: message.setRecipients(Message.RecipientType.CC, "");
084: message.setRecipients(Message.RecipientType.BCC, "");
085: }
086: } catch (MessagingException ex) {
087: log.error("Cannot change email recipients", ex);
088:
089: throw new MailPreparationException(
090: "Cannot change email recipients", ex);
091: }
092: }
093:
094: /**
095: * DOCUMENT ME!
096: *
097: * @param email DOCUMENT ME!
098: *
099: * @throws EmailerException DOCUMENT ME!
100: */
101: public void sendMessage(Email email) throws EmailerException {
102: // Sanity check
103: if (email == null) {
104: log.warn("Missing or invalid email instance.");
105: throw new EmailerException(
106: "Missing or invalid email instance.");
107: }
108:
109: // Throws EmailerException describing the validation error
110: validate(email);
111:
112: MimeMessage mailMsg = new MimeMessage(this .getSession());
113: InternetAddress[] addresses = null;
114:
115: try {
116: // Set email message priorities
117: mailMsg.setHeader("X-Priority", getXPriority(email));
118: mailMsg
119: .setHeader("Importance",
120: getMsOutlookPriority(email));
121:
122: // Verify the recipient email address
123: if (StringUtils.isNotBlank(email.getToName())) {
124: log.debug("Parsing recipient email addresses: '"
125: + email.getToName() + "'");
126: addresses = InternetAddress.parse(email.getToName(),
127: false);
128: mailMsg.setRecipients(Message.RecipientType.TO,
129: addresses);
130: } else {
131: log.error("Missing or invalid 'to' in email address.");
132: throw new EmailerException(
133: "Missing or invalid 'to' in email address.");
134: }
135:
136: // Set the CC if defined
137: if (StringUtils.isNotBlank(email.getCarbonCopy())) {
138: log.debug("Parsing cc email addreses: '"
139: + email.getCarbonCopy() + "'");
140: addresses = InternetAddress.parse(
141: email.getCarbonCopy(), false);
142: mailMsg.setRecipients(Message.RecipientType.CC,
143: addresses);
144: }
145:
146: if (StringUtils.isNotBlank(email.getFromName())) {
147: log.debug("Setting From name: '" + email.getFromName()
148: + "'");
149: mailMsg.setFrom(new InternetAddress(
150: email.getFromName(), ""));
151: } else {
152: // insert bean-specific from email
153: log.debug("Setting From name: '" + fromMailAccount
154: + "'");
155: mailMsg.setFrom(new InternetAddress(fromMailAccount,
156: "EmForge Messaging Service"));
157: }
158:
159: if (StringUtils.isNotBlank(email.getSubject())) {
160: log.debug("Setting subject: '" + email.getSubject()
161: + "'");
162: mailMsg.setSubject(email.getSubject());
163: }
164:
165: Multipart mp = new MimeMultipart("alternative");
166: if (StringUtils.isNotBlank(email.getContent())) {
167: BodyPart bpText = new MimeBodyPart();
168: bpText.setContent(email.getContent(), "text/plain");
169: mp.addBodyPart(bpText);
170: }
171:
172: if (StringUtils.isNotBlank(email.getHtmlContent())) {
173: BodyPart bpText = new MimeBodyPart();
174: bpText.setContent(email.getHtmlContent(), "text/html");
175: mp.addBodyPart(bpText);
176: }
177:
178: mailMsg.setContent(mp);
179:
180: // Configure the email properties
181: mailMsg.setSentDate(new java.util.Date());
182:
183: // Send the mail message. Throws a SendFailedException if any of the
184: // recipients of the message have an invalid email address
185: send(mailMsg);
186:
187: if (emailLogger != null) {
188: emailLogger.logEmail(email);
189: }
190: } catch (Exception ex) {
191: try {
192: log.error(ex.getMessage());
193: } catch (Exception ex2) {
194: //sometime we got NPE from org.springframework.mail.MailSendException.getMessage(MailSendException.java:111
195: // just ignore it and write default message
196: log.error("Cannot send email: Unknown Error");
197: }
198:
199: throw new EmailerException(ex.getMessage());
200: } finally {
201: }
202: }
203:
204: protected void validate(Email email) throws EmailerException {
205: /*
206: String[] array = StringUtils.split(email.getToName(), ',');
207:
208: Will implement later
209: for (int i = 0; i < array.length; i++) {
210: if (! PatternValidator.validate(array[i], PatternValidator.EMAIL_REGEX)) {
211: throw new EmailerException("Invalid email address found in recipient field. Value='" + array[i] + "'");
212: }
213: }
214:
215: if (StringUtils.isNotEmpty(email.getCarbonCopy()) && ! PatternValidator.validate(email.getCarbonCopy(), PatternValidator.EMAIL_REGEX)) {
216: throw new EmailerException("Invalid email address found in cc field. Value='" + email.getCarbonCopy() + "'");
217: }
218: */
219: }
220:
221: /**
222: * DOCUMENT ME!
223: *
224: * @param priority DOCUMENT ME!
225: *
226: * @return DOCUMENT ME!
227: */
228: public static boolean isValidPriority(int priority) {
229: if ((priority < EmailSender.PRIORITY_NORMAL)
230: || (priority > EmailSender.PRIORITY_HIGH)) {
231: return false;
232: } else {
233: return true;
234: }
235: }
236:
237: /**
238: * DOCUMENT ME!
239: *
240: * @param email DOCUMENT ME!
241: *
242: * @return DOCUMENT ME!
243: */
244: protected String getXPriority(Email email) {
245: if (email.getPriority() == EmailSender.PRIORITY_NORMAL) {
246: return "3";
247: } else if (email.getPriority() == EmailSender.PRIORITY_ELEVATED) {
248: return "2";
249: } else {
250: return "1";
251: }
252: }
253:
254: /**
255: * DOCUMENT ME!
256: *
257: * @param email DOCUMENT ME!
258: *
259: * @return DOCUMENT ME!
260: */
261: String getMsOutlookPriority(Email email) {
262: if (email.getPriority() == EmailSender.PRIORITY_NORMAL) {
263: return "low";
264: } else if (email.getPriority() == EmailSender.PRIORITY_ELEVATED) {
265: return "normal";
266: } else {
267: return "high";
268: }
269: }
270:
271: }
|