Java tutorial
/* * imoten - i mode.net mail tensou(forward) * * Copyright (C) 2010 shoozhoo (http://code.google.com/p/imoten/) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * */ package immf; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.activation.DataHandler; import javax.mail.BodyPart; import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeUtility; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.mail.ByteArrayDataSource; import org.apache.commons.mail.Email; import org.apache.commons.mail.EmailException; public class ImodeForwardMail extends MyHtmlEmail { private static final Log log = LogFactory.getLog(ImodeForwardMail.class); private ImodeMail imm; private Config conf; private static CharacterConverter subjectCharConv = null; private static CharacterConverter goomojiSubjectCharConv = null; private static StringConverter strConv = null; public ImodeForwardMail(ImodeMail imm, Config conf) throws EmailException { this.imm = imm; this.conf = conf; this.setDebug(conf.isMailDebugEnable()); this.setCharset(this.conf.getMailEncode()); this.setContentTransferEncoding(this.conf.getContentTransferEncoding()); // SMTP Server this.setHostName(conf.getSmtpServer()); this.setSmtpPort(conf.getSmtpPort()); this.setSocketConnectionTimeout(conf.getSmtpConnectTimeoutSec() * 1000); this.setSocketTimeout(conf.getSmtpTimeoutSec() * 1000); this.setTLS(conf.isSmtpTls()); if (!StringUtils.isBlank(conf.getSmtpUser())) { this.setAuthentication(conf.getSmtpUser(), conf.getSmtpPasswd()); } if (!StringUtils.isBlank(conf.getPopServer()) && !StringUtils.isBlank(conf.getPopUser())) { // POP before SMTP this.setPopBeforeSmtp(true, conf.getPopServer(), conf.getPopUser(), conf.getPopPasswd()); } this.setFrom(conf.getSmtpMailAddress()); if (!conf.getForwardReplyTo().isEmpty()) { for (String addr : conf.getForwardReplyTo()) { this.addReplyTo(addr); } } String subject = null; if (imm.getFolderId() == ImodeNetClient.FolderIdSent) { subject = conf.getSentSubjectAppendPrefix() + imm.getSubject() + conf.getSentSubjectAppendSuffix(); } else { subject = conf.getSubjectAppendPrefix() + imm.getSubject() + conf.getSubjectAppendSuffix(); } if (conf.isSubjectEmojiReplace()) { this.setSubject(EmojiUtil.replaceToLabel(subject)); } else { this.setSubject(subject); } List<String> list = conf.getForwardTo(); for (String addr : list) { this.addTo(addr); } list = conf.getForwardCc(); for (String addr : list) { this.addCc(addr); } list = conf.getForwardBcc(); for (String addr : list) { this.addBcc(addr); } // ? if (this.imm.getFolderId() != ImodeNetClient.FolderIdSent && true) { this.imm.setBody(ImodeForwardMail.strConv.convert(this.imm.getBody())); } Config.BodyEmojiReplace emojiReplace = conf.getBodyEmojiReplace(); if (emojiReplace == Config.BodyEmojiReplace.DontReplace) { this.setBodyDontReplace(); } else if (emojiReplace == Config.BodyEmojiReplace.ToInlineImage) { this.setBodyToInlineImage(); } else if (emojiReplace == Config.BodyEmojiReplace.ToWebLink) { this.setBodyToWebLink(); } else if (emojiReplace == Config.BodyEmojiReplace.ToLabel) { this.setBodyToLabel(); } else if (emojiReplace == Config.BodyEmojiReplace.ToSubjectTable) { this.imm.setBody(ImodeForwardMail.subjectCharConv.convert(this.imm.getBody())); this.setBodyDontReplace(); } // this.attacheFile(); this.attacheInline(); } /* * ?<img src=".....">????? * imode.net?html??[cid:]?????????? */ private static String cidAddedBody(String html, List<AttachedFile> inlines) { for (AttachedFile f : inlines) { html = StringUtils.replace(html, f.getId(), "cid:" + f.getId()); } return html; } /* * ????????? */ private void setBodyDontReplace() throws EmailException { String html = this.imm.getBody(); String plain = this.imm.getBody(); if (this.imm.isDecomeFlg()) { // HTML plain = Util.html2text(plain); } else { String fontfamily = conf.getMailFontFamily(); if (fontfamily != null) { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;font-family:\'" + fontfamily + "\';\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } else { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } } this.setBodyDontReplace(plain, html, this.imm.getInlineFileList()); } private void setBodyDontReplace(String plainText, String html, List<AttachedFile> inlineFiles) throws EmailException { // html html = cidAddedBody(html, inlineFiles); if (conf.isHeaderToBody()) { html = html.replaceAll("(<body[^>]*>)", "$1" + Util.getHeaderInfo(this.imm, true, this.conf.isSubjectEmojiReplace(), conf)); } // if (conf.isHeaderToBody()) { plainText = Util.getHeaderInfo(this.imm, false, this.conf.isSubjectEmojiReplace(), conf) + plainText; } html = "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=" + this.charset + "\"></head>" + html + "</html>"; try { this.setHtmlMsg(html); if (conf.isMailAlternative()) { this.setTextMsg(plainText); } } catch (Exception e) { throw new EmailException(e); } } private void setBodyToInlineImage() throws EmailException { String html = this.imm.getBody(); String plain = this.imm.getBody(); String va; String px; if (this.imm.isDecomeFlg()) { // HTML plain = Util.html2text(EmojiUtil.replaceToLabel(plain)); va = conf.getBodyEmojiVAlignHtml(); px = conf.getBodyEmojiSizeHtml(); } else { String fontfamily = conf.getMailFontFamily(); if (fontfamily != null) { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;font-family:\'" + fontfamily + "\';\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } else { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } plain = EmojiUtil.replaceToLabel(plain); va = conf.getBodyEmojiVAlign(); px = conf.getBodyEmojiSize(); } Map<URL, String> emojiToCid = new HashMap<URL, String>(); StringBuilder buf = new StringBuilder(); for (char c : html.toCharArray()) { if (!EmojiUtil.isEmoji(c)) { buf.append(c); continue; } try { URL emojiUrl = EmojiUtil.emojiToImageUrl(c); if (emojiUrl == null) { buf.append(EmojiUtil.UnknownReplace); } else { String cid = emojiToCid.get(emojiUrl); if (cid == null) { cid = this.embed(emojiUrl, "emoji" + ((int) c)); emojiToCid.put(emojiUrl, cid); } String wh = ""; if (px != null) { wh = " width: " + px + "; height: " + px + ";"; } buf.append("<img src=\"cid:" + cid + "\" style=\"margin: 0pt 0.2ex; vertical-align: " + va + ";" + wh + "\">"); } } catch (Exception e) { log.warn("Emoji to inline image Error.", e); buf.append(EmojiUtil.UnknownReplace); } } this.setBodyDontReplace(plain, buf.toString(), this.imm.getInlineFileList()); } private void setBodyToWebLink() throws EmailException { String html = this.imm.getBody(); String plain = this.imm.getBody(); String va; String px; if (this.imm.isDecomeFlg()) { // HTML va = conf.getBodyEmojiVAlignHtml(); px = conf.getBodyEmojiSizeHtml(); html = EmojiUtil.replaceToWebLink(html, va, px); plain = Util.html2text(EmojiUtil.replaceToLabel(plain)); } else { String fontfamily = conf.getMailFontFamily(); if (fontfamily != null) { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;font-family:\'" + fontfamily + "\';\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } else { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } va = conf.getBodyEmojiVAlign(); px = conf.getBodyEmojiSize(); html = EmojiUtil.replaceToWebLink(html, va, px); plain = EmojiUtil.replaceToLabel(plain); } this.setBodyDontReplace(plain, html, this.imm.getInlineFileList()); } private void setBodyToLabel() throws EmailException { String html = this.imm.getBody(); String plain = this.imm.getBody(); if (this.imm.isDecomeFlg()) { // HTML html = EmojiUtil.replaceToLabel(html); plain = Util.html2text(EmojiUtil.replaceToLabel(plain)); } else { String fontfamily = conf.getMailFontFamily(); if (fontfamily != null) { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;font-family:\'" + fontfamily + "\';\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } else { html = "<body><pre style=\"white-space:pre-wrap;word-wrap:break-word;\">" + Util.easyEscapeHtml(html) + "</pre></body>"; } html = EmojiUtil.replaceToLabel(html); plain = EmojiUtil.replaceToLabel(plain); } this.setBodyDontReplace(plain, html, this.imm.getInlineFileList()); } /* * ? */ private void attacheFile() throws EmailException { try { List<AttachedFile> files = this.imm.getAttachFileList(); for (AttachedFile f : files) { BodyPart part = createBodyPart(); part.setDataHandler(new DataHandler(new ByteArrayDataSource(f.getData(), f.getContentType()))); Util.setFileName(part, f.getFilename(), this.charset, null); part.setDisposition(BodyPart.ATTACHMENT); getContainer().addBodyPart(part); } } catch (Exception e) { throw new EmailException(e); } } /* * Inline?? */ private void attacheInline() throws EmailException { try { List<AttachedFile> files = this.imm.getInlineFileList(); for (AttachedFile f : files) { this.embed(new ByteArrayDataSource(f.getData(), f.getContentType()), f.getFilename(), this.charset, f.getId()); } } catch (Exception e) { throw new EmailException(e); } } @Override public void buildMimeMessage() throws EmailException { super.buildMimeMessage(); MimeMessage msg = this.getMimeMessage(); try { msg.setHeader("X-Mailer", ServerMain.Version); if (!this.conf.isRewriteAddress()) { // ??imode???????? msg.setHeader("Resent-From", this.conf.getSmtpMailAddress()); if (!this.conf.getForwardTo().isEmpty()) { msg.setHeader("Resent-To", StringUtils.join(this.conf.getForwardTo(), ",")); } if (!this.conf.getForwardCc().isEmpty()) { msg.setHeader("Resent-Cc", StringUtils.join(this.conf.getForwardCc(), ",")); } if (!this.conf.getForwardBcc().isEmpty()) { msg.setHeader("Resent-Bcc", StringUtils.join(this.conf.getForwardBcc(), ",")); } SimpleDateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z (z)", Locale.US); msg.setHeader("Resent-Date", df.format(new Date())); msg.setHeader("Date", df.format(this.imm.getTimeDate())); msg.removeHeader("To"); msg.removeHeader("Cc"); msg.removeHeader("Bcc"); List<InternetAddress> tolist = new ArrayList<InternetAddress>(); List<InternetAddress> cclist = new ArrayList<InternetAddress>(); boolean useMyAddress = false; if (this.imm.getFolderId() != ImodeNetClient.FolderIdSent) { if (this.conf.isHideMyaddr()) { if (this.imm.getToAddrList().size() == 0) { useMyAddress = true; } } else { useMyAddress = true; } } if (useMyAddress) { switch (this.imm.getRecvType()) { case ImodeMail.RECV_TYPE_TO: tolist.add(this.imm.getMyInternetAddress()); break; case ImodeMail.RECV_TYPE_CC: cclist.add(this.imm.getMyInternetAddress()); break; case ImodeMail.RECV_TYPE_BCC: break; } } tolist.addAll(this.imm.getToAddrList()); cclist.addAll(this.imm.getCcAddrList()); msg.setHeader("To", InternetAddress.toString(tolist.toArray(new InternetAddress[0]))); if (this.imm.getCcAddrList().size() > 0) { msg.setHeader("Cc", InternetAddress.toString(cclist.toArray(new InternetAddress[0]))); } msg.setFrom(this.imm.getFromAddr()); } String subject = null; if (imm.getFolderId() == ImodeNetClient.FolderIdSent) { subject = conf.getSentSubjectAppendPrefix() + imm.getSubject() + conf.getSentSubjectAppendSuffix(); } else { subject = conf.getSubjectAppendPrefix() + imm.getSubject() + conf.getSubjectAppendSuffix(); } if (conf.isSubjectEmojiReplace()) { subject = EmojiUtil.replaceToLabel(subject); } if (ImodeForwardMail.goomojiSubjectCharConv != null) { String goomojiSubject = ImodeForwardMail.goomojiSubjectCharConv.convert(subject); msg.setHeader("X-Goomoji-Source", "docomo_ne_jp"); msg.setHeader("X-Goomoji-Subject", Util.encodeGoomojiSubject(goomojiSubject)); } subject = ImodeForwardMail.subjectCharConv.convert(subject); msg.setSubject(MimeUtility.encodeText(subject, this.charset, "B")); if (this.conf.getContentTransferEncoding() != null) { msg.setHeader("Content-Transfer-Encoding", this.conf.getContentTransferEncoding()); } } catch (Exception e) { log.warn(e); } } @Override protected MimeMessage createMimeMessage(Session aSession) { List<InternetAddress> recipients = new ArrayList<InternetAddress>(); List<String> list = conf.getForwardTo(); for (String addr : list) { try { recipients.add(new InternetAddress(addr)); } catch (Exception e) { log.warn("ForwardTo error " + addr, e); } } list = conf.getForwardCc(); for (String addr : list) { try { recipients.add(new InternetAddress(addr)); } catch (Exception e) { log.warn("ForwardCc error " + addr, e); } } list = conf.getForwardBcc(); for (String addr : list) { try { recipients.add(new InternetAddress(addr)); } catch (Exception e) { log.warn("ForwardBcc error " + addr, e); } } String from = this.conf.getSmtpMailAddress(); try { return new MyMimeMessage(aSession, new InternetAddress(from), recipients); } catch (Exception e) { log.warn("From error " + from, e); return null; } } @Override public MyHtmlEmail setHtmlMsg(String html) throws EmailException { html = Util.replaceUnicodeMapping(html); html += "\n"; try { html = new String(html.getBytes(this.charset)); } catch (Exception e) { log.error("setHtmlMsg", e); } return super.setHtmlMsg(html); } @Override public Email setSubject(String subject) { return super.setSubject(Util.replaceUnicodeMapping(subject)); } public static void setSubjectCharConv(CharacterConverter subjectCharConv) { ImodeForwardMail.subjectCharConv = subjectCharConv; } public static void setGoomojiSubjectCharConv(CharacterConverter goomojiSubjectCharConv) { ImodeForwardMail.goomojiSubjectCharConv = goomojiSubjectCharConv; } public static void setStrConv(StringConverter strConv) { ImodeForwardMail.strConv = strConv; } }