package cn.jcenterhome.util;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.mail.smtp.SMTPTransport;
public class Mail {
private final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
private boolean mailUserName = true;
private String host = null;
private int port = 25;
private boolean auth = true;
private String username = null;
private String password = null;
private HttpServletRequest request = null;
private Session session = null;
ThreadPoolExecutor executor = null;
{
executor = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5));
}
@SuppressWarnings("unchecked")
public Mail(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
Map<String, Object> globalMail = Common.getCacheDate(request, response, "/data/cache/cache_mail.jsp",
"globalMail");
if ((Integer) globalMail.get("mailusername") == 0) {
mailUserName = false;
}
host = globalMail.get("server").toString();
port = (Integer) globalMail.get("port");
if (port == 0) {
port = 25;
}
if ((Integer) globalMail.get("auth") == 0) {
auth = false;
}
username = globalMail.get("auth_username").toString();
password = globalMail.get("auth_password").toString();
}
private synchronized void createSession() {
Properties mailProps = new Properties();
mailProps.setProperty("mail.transport.protocol", "smtp");
mailProps.setProperty("mail.smtp.host", host);
mailProps.setProperty("mail.smtp.port", String.valueOf(port));
if ("smtp.gmail.com".equals(host)) {
mailProps.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
mailProps.setProperty("mail.smtp.socketFactory.fallback", "false");
mailProps.setProperty("mail.smtp.socketFactory.port", String.valueOf(port));
}
if (auth) {
mailProps.put("mail.smtp.auth", "true");
}
session = Session.getDefaultInstance(mailProps, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
private MimeMessage createMimeMessage() {
if (session == null) {
createSession();
}
return new MimeMessage(session);
}
public boolean sendMessage(String from, String toEmail, String subject, String body) {
String charset = JavaCenterHome.JCH_CHARSET;
Map<String, Object> sConfig = (Map<String, Object>) request.getAttribute("sConfig");
Map<String, Object> sGlobal = (Map<String, Object>) request.getAttribute("sGlobal");
String siteName = (String) sConfig.get("sitename");
int timestamp = (Integer) sGlobal.get("timestamp");
String timeoffset = Common.getTimeOffset(sGlobal, sConfig);
body = Common.getMessage(request, "template_sendmail", siteName, body, Common.getSiteUrl(request),
Common.gmdate("yyyy-MM-dd HH:mm", timestamp, timeoffset));
try {
if (from == null) {
from = MimeUtility.encodeText(siteName, charset, "B") + " <" + sConfig.get("adminemail")
+ ">";
} else {
List<String> mats = Common.pregMatch(from, "^(.+?) \\<(.+?)\\>$");
if (mats.size() == 2) {
from = MimeUtility.encodeText(mats.get(0), charset, "B") + " <" + mats.get(1) + ">";
}
}
List<String> mats = Common.pregMatch(toEmail, "^(.+?) \\<(.+?)\\>$");
if (mats.size() == 2) {
toEmail = mailUserName ? MimeUtility.encodeText(mats.get(0), charset, "B") + " <"
+ mats.get(1) + ">" : mats.get(1);
}
subject = MimeUtility.encodeText(("[" + siteName + "] " + subject).replaceAll("[\r|\n]", ""),
charset, "B");
body = body.replaceAll("\n\r", "\r").replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll(
"\n", "\r\n");
String encoding = MimeUtility.mimeCharset(charset);
String toEmails[] = toEmail.split(",");
Address to[] = new Address[toEmails.length];
for (int i = 0; i < toEmails.length; i++) {
String sTo = toEmails[i];
if (sTo.matches("^.*<.*>$")) {
int index = sTo.indexOf("<");
to[i] = new InternetAddress(sTo.substring(index + 1, sTo.length() - 1),
mailUserName ? sTo.substring(0, index) : "", encoding);
} else {
to[i] = new InternetAddress(sTo, "", encoding);
}
}
String fromName = "";
String fromEmail;
if (from.matches("^.*<.*>$")) {
int index = from.indexOf("<");
if (mailUserName) {
fromName = from.substring(0, index);
}
fromEmail = from.substring(index + 1, from.length() - 1);
} else {
fromEmail = from;
}
Address fromAddress = new InternetAddress(fromEmail, fromName, encoding);
MimeMessage message = createMimeMessage();
message.setHeader("X-Priority", "3");
message.setHeader("Date", Common.gmdate("EEE, dd MMM yyyy HH:mm:ss Z", timestamp, timeoffset));
message.setHeader("Content-Transfer-Encoding", "8bit");
message.setRecipients(Message.RecipientType.TO, to);
message.setFrom(fromAddress);
message.setSubject(subject, encoding);
MimeMultipart content = new MimeMultipart("alternative");
if (body != null) {
MimeBodyPart html = new MimeBodyPart();
html.setContent(body, "text/html;charset=" + encoding);
html.setDisposition(Part.INLINE);
content.addBodyPart(html);
}
message.setContent(content);
message.setDisposition(Part.INLINE);
sendMessages(message);
} catch (Exception e) {
FileHelper.writeLog(request, "SMTP", "(" + this.host + ":" + this.port + ") END - "
+ e.getMessage());
return false;
}
return true;
}
private void sendMessages(MimeMessage message) {
Collection<MimeMessage> messages = Collections.singletonList(message);
if (messages.size() == 0) {
return;
}
executor.execute(new EmailTask(messages));
}
private class EmailTask implements Runnable {
private Collection<MimeMessage> messages;
private int timestamp;
private String timeoffset;
private String onlineIP;
private int supe_uid;
private String requestURI;
public EmailTask(Collection<MimeMessage> messages) {
this.messages = messages;
Map<String, Object> sGlobal = (Map<String, Object>) request.getAttribute("sGlobal");
Map<String, Object> sConfig = (Map<String, Object>) request.getAttribute("sConfig");
this.timestamp = (Integer) sGlobal.get("timestamp");
this.timeoffset = Common.getTimeOffset(sGlobal, sConfig);
this.onlineIP = Common.getOnlineIP(request);
this.supe_uid = (Integer) sGlobal.get("supe_uid");
this.requestURI = (String) request.getAttribute("requestURI");
}
public void run() {
try {
sendMessages();
} catch (MessagingException me) {
String message = me.getMessage();
if (message == null) {
message = "";
}
message = "(" + host + ":" + port + ") CONNECT - Unable to connect to the SMTP server��"
+ message.replace("\t", "");
FileHelper.writeLog(timestamp, timeoffset, onlineIP, supe_uid, requestURI, "SMTP", message);
}
}
public void sendMessages() throws MessagingException {
Transport transport = null;
try {
URLName url = new URLName("smtp", host, port, "", username, password);
transport = new SMTPTransport(session, url);
transport.connect(host, port, username, password);
for (MimeMessage message : messages) {
transport.sendMessage(message, message.getRecipients(MimeMessage.RecipientType.TO));
}
} finally {
if (transport != null) {
transport.close();
}
}
}
}
}