1 package com.ozacc.mail.fetch.impl;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.util.ArrayList;
6 import java.util.Date;
7 import java.util.Enumeration;
8 import java.util.List;
9
10 import javax.mail.Address;
11 import javax.mail.Header;
12 import javax.mail.Message;
13 import javax.mail.MessagingException;
14 import javax.mail.internet.AddressException;
15 import javax.mail.internet.InternetAddress;
16 import javax.mail.internet.MimeMessage;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 import com.ozacc.mail.fetch.ReceivedMail;
22 import com.ozacc.mail.fetch.impl.sk_jp.AttachmentsExtractor;
23 import com.ozacc.mail.fetch.impl.sk_jp.HtmlPartExtractor;
24 import com.ozacc.mail.fetch.impl.sk_jp.MultipartUtility;
25
26 /***
27 * MimeMessageからMailを生成するクラス。
28 * <p>
29 * 変換時に生じたチェック例外は、このクラス内でキャッチされ無視されます。
30 * 例外が生じた項目(差出人や宛先など)に該当するMailインスタンスのプロパティには何もセットされません。
31 *
32 * @since 1.2
33 * @author Tomohiro Otsuka
34 * @version $Id: MailConverter.java,v 1.1.2.8 2005/01/18 07:21:20 otsuka Exp $
35 */
36 public class MailConverter {
37
38 private static Log log = LogFactory.getLog(MailConverter.class);
39
40 private MimeMessage[] messages;
41
42 /***
43 * @param mimeMessage
44 */
45 public MailConverter(MimeMessage mimeMessage) {
46 this(new MimeMessage[] { mimeMessage });
47 }
48
49 /***
50 * @param mimeMessages
51 */
52 public MailConverter(MimeMessage[] mimeMessages) {
53 this.messages = mimeMessages;
54 }
55
56 /***
57 * @return
58 */
59 public ReceivedMail[] convertIntoMails() {
60 log.debug("計" + messages.length + "通のMimeMessageをMailに変換します。");
61 List list = new ArrayList();
62 for (int i = 0; i < messages.length; i++) {
63 log.debug((i + 1) + "通目のMimeMessageをMailに変換します。");
64
65 MimeMessage mm = messages[i];
66 ReceivedMail mail = new ReceivedMail();
67
68 setReturnPath(mm, mail);
69 setDate(mm, mail);
70 setFromAddress(mm, mail);
71 setRecipientAddresses(mm, mail);
72 setMessageId(mm, mail);
73 setReplyToAddress(mm, mail);
74 setSubject(mm, mail);
75 setXHeaders(mm, mail);
76 setText(mm, mail);
77 setHtmlText(mm, mail);
78 setAttachmentFiles(mm, mail);
79
80 setSize(mm, mail);
81
82 mail.setMessage(mm);
83
84 log.debug((i + 1) + "通目のMimeMessageをMailに変換しました。");
85 log.debug(mail.toString());
86
87 list.add(mail);
88 }
89 log.debug("計" + messages.length + "通のMimeMessageをMailに変換しました。");
90 return (ReceivedMail[])list.toArray(new ReceivedMail[list.size()]);
91 }
92
93 /***
94 * 指定されたMimeMessageに添付されているファイルを全て抽出し、
95 * 指定されたReceivedMailにセットします。
96 *
97 * @param mm
98 * @param mail
99 */
100 private void setAttachmentFiles(MimeMessage mm, ReceivedMail mail) {
101 try {
102 AttachmentsExtractor ae = new AttachmentsExtractor(
103 AttachmentsExtractor.MODE_IGNORE_MESSAGE
104 | AttachmentsExtractor.MODE_IGNORE_INLINE);
105 MultipartUtility.process(mm, ae);
106 for (int i = 0, num = ae.getCount(); i < num; i++) {
107 String fileName = ae.getFileName(i);
108 InputStream is = ae.getInputStream(i);
109 mail.addFile(is, fileName);
110 }
111 } catch (IOException e) {
112 log.error("添付ファイルの取得に失敗しました。", e);
113 } catch (MessagingException e) {
114
115 log.warn(e.getMessage());
116 }
117 }
118
119 private void setXHeaders(MimeMessage mm, ReceivedMail mail) {
120 log.debug("X-HeaderをMailにセットします。");
121 String[] xHeaders = null;
122 Enumeration headerEnum = null;
123 try {
124 headerEnum = mm.getAllHeaders();
125 } catch (MessagingException e) {
126
127 log.warn(e.getMessage());
128 }
129 while (headerEnum != null && headerEnum.hasMoreElements()) {
130 Header header = (Header)headerEnum.nextElement();
131 if (header.getName().startsWith("X-")) {
132 mail.addXHeader(header.getName(), header.getValue());
133 }
134 }
135 }
136
137 private void setReplyToAddress(MimeMessage mm, ReceivedMail mail) {
138 log.debug("Reply-ToアドレスをMailにセットします。");
139 Address[] addresses = null;
140 try {
141 addresses = mm.getReplyTo();
142 } catch (MessagingException e) {
143
144 log.warn(e.getMessage());
145 }
146 if (addresses != null) {
147 log.debug(addresses.length + "つのReply-Toアドレスが見つかりました。最初のアドレスのみ取得されます。");
148 for (int j = 0; j < addresses.length; j++) {
149 Address address = addresses[j];
150 mail.setReplyTo((InternetAddress)address);
151 break;
152 }
153 } else {
154 log.debug("Reply-Toアドレスは見つかりませんでした。");
155 }
156 }
157
158 /***
159 * メールの容量(byte)をMimeMessageから取得してReceivedMailにセットします。
160 * 取得に失敗した場合は -1 をセットします。
161 *
162 * @param mm
163 * @param mail
164 */
165 private void setSize(MimeMessage mm, ReceivedMail mail) {
166 try {
167 mail.setSize(mm.getSize());
168 } catch (MessagingException e) {
169 mail.setSize(-1);
170 }
171 }
172
173 /***
174 * @param mm
175 * @param mail
176 * @throws MessagingException
177 */
178 private void setHtmlText(MimeMessage mm, ReceivedMail mail) {
179 try {
180 HtmlPartExtractor hpe = new HtmlPartExtractor();
181 MultipartUtility.process(mm, hpe);
182 String htmlText = hpe.getHtml();
183 mail.setHtmlText(htmlText);
184 } catch (MessagingException e) {
185
186 log.warn(e.getMessage());
187 }
188 }
189
190 private void setText(MimeMessage mm, ReceivedMail mail) {
191 try {
192 String text = MultipartUtility.getPlainText(mm);
193 mail.setText(text);
194 } catch (MessagingException e) {
195
196 log.warn(e.getMessage());
197 }
198 }
199
200 private void setMessageId(MimeMessage mm, ReceivedMail mail) {
201 try {
202 String messageId = mm.getMessageID();
203 mail.setMessageId(messageId);
204 } catch (MessagingException e) {
205
206 log.warn(e.getMessage());
207 }
208 }
209
210 private void setSubject(MimeMessage mm, ReceivedMail mail) {
211 try {
212 String subject = mm.getSubject();
213 mail.setSubject(subject);
214 } catch (MessagingException e) {
215
216 log.warn(e.getMessage());
217 }
218 }
219
220 private void setDate(MimeMessage mm, ReceivedMail mail) {
221 try {
222 Date d = mm.getSentDate();
223 mail.setDate(d);
224 } catch (MessagingException e) {
225
226 log.warn(e.getMessage());
227 }
228 }
229
230 /***
231 * Return-Pathアドレスは必ずしもセットされてはいません。
232 * 特にspam系のメールでは不正なフォーマットのメールアドレスが
233 * セットされている場合もあるので要注意。
234 *
235 * @param mm
236 * @param mail
237 */
238 private void setReturnPath(MimeMessage mm, ReceivedMail mail) {
239 log.debug("Return-Pathアドレスを検出します。");
240 String[] returnPath = null;
241 try {
242 returnPath = mm.getHeader("Return-Path");
243 } catch (MessagingException e) {
244
245 log.warn(e.getMessage());
246 }
247 if (returnPath != null && returnPath.length > 0) {
248 String email = returnPath[0].substring(1, returnPath[0].length() - 1);
249 if (email.length() > 0) {
250 try {
251 mail.setReturnPath(email);
252 log.debug("Return-PathアドレスをMailにセットしました。[Return-Path='" + email + "']");
253 } catch (IllegalArgumentException e) {
254 log.warn("Return-Pathアドレスが不正なメールアドレスフォーマットです。[Return-Path='" + email + "']");
255 }
256 } else {
257 log.debug("Return-Pathアドレスは見つかりませんでした。");
258 }
259 } else {
260 log.debug("Return-Pathアドレスは見つかりませんでした。");
261 }
262 }
263
264 private void setFromAddress(MimeMessage mm, ReceivedMail mail) {
265 log.debug("Fromアドレスを検出します。");
266 Address[] addresses = null;
267 try {
268 addresses = mm.getFrom();
269 } catch (MessagingException e) {
270
271 log.warn(e.getMessage());
272 }
273 if (addresses != null) {
274 log.debug(addresses.length + "つのFromアドレスが見つかりました。");
275 for (int j = 0; j < addresses.length; j++) {
276 InternetAddress address = (InternetAddress)addresses[j];
277 mail.setFrom(address);
278 log.debug("FromアドレスをMailにセットしました。[From='" + address.toUnicodeString() + "']");
279 }
280 } else {
281 log.debug("Fromアドレスは見つかりませんでした。");
282 }
283 }
284
285 private void setRecipientAddresses(MimeMessage mm, ReceivedMail mail) {
286
287
288
289 log.debug("Toアドレスを検出します。");
290 Address[] toAddresses = null;
291 try {
292 toAddresses = mm.getRecipients(Message.RecipientType.TO);
293 } catch (AddressException e) {
294 log.warn("不正なメールアドレスが検出されました。[" + e.getRef() + "]");
295 } catch (MessagingException e) {
296
297 log.warn(e.getMessage());
298 }
299 if (toAddresses != null) {
300 log.debug(toAddresses.length + "つのToアドレスが見つかりました。");
301 for (int j = 0; j < toAddresses.length; j++) {
302 InternetAddress address = (InternetAddress)toAddresses[j];
303 mail.addTo(address);
304 log.debug("ToアドレスをMailにセットしました。[To='" + address.toUnicodeString() + "']");
305 }
306 } else {
307 log.debug("Toアドレスは見つかりませんでした。");
308 }
309
310
311
312
313 log.debug("Ccアドレスを検出します。");
314 Address[] ccAddresses = null;
315 try {
316 ccAddresses = mm.getRecipients(Message.RecipientType.CC);
317 } catch (AddressException e) {
318 log.warn("不正なメールアドレスが検出されました。[" + e.getRef() + "]");
319 } catch (MessagingException e) {
320
321 log.warn(e.getMessage());
322 }
323 if (ccAddresses != null) {
324 log.debug(ccAddresses.length + "つのCcアドレスが見つかりました。");
325 for (int j = 0; j < ccAddresses.length; j++) {
326 InternetAddress address = (InternetAddress)ccAddresses[j];
327 mail.addCc(address);
328 log.debug("CcアドレスをMailにセットしました。[Cc='" + address.toUnicodeString() + "']");
329 }
330 } else {
331 log.debug("Ccアドレスは見つかりませんでした。");
332 }
333 }
334
335 }