OSDN Git Service

CVS最新版の全ファイルを追加
[spring-ext/ozacc-mail.git] / src / java / com / ozacc / mail / impl / MimeMessageBuilder.java
1 package com.ozacc.mail.impl;\r
2 \r
3 import java.io.UnsupportedEncodingException;\r
4 import java.util.Iterator;\r
5 import java.util.Map;\r
6 \r
7 import javax.activation.DataHandler;\r
8 import javax.activation.DataSource;\r
9 import javax.mail.MessagingException;\r
10 import javax.mail.internet.InternetAddress;\r
11 import javax.mail.internet.MimeBodyPart;\r
12 import javax.mail.internet.MimeMessage;\r
13 import javax.mail.internet.MimeMultipart;\r
14 import javax.mail.internet.MimePart;\r
15 import javax.mail.internet.MimeUtility;\r
16 \r
17 import com.ozacc.mail.Mail;\r
18 \r
19 /**\r
20  * MimeMessageインスタンスを生成するクラス。Mail一通毎に生成されます。\r
21  * \r
22  * @since 1.0\r
23  * @author Tomohiro Otsuka\r
24  * @version $Id: MimeMessageBuilder.java,v 1.11.2.2 2007/03/30 13:03:44 otsuka Exp $\r
25  */\r
26 public class MimeMessageBuilder {\r
27 \r
28         private MimeMessage mimeMessage;\r
29 \r
30         private String charset = Mail.JIS_CHARSET;\r
31 \r
32         private boolean hasRecipient = false;\r
33 \r
34         /**\r
35          * コンストラクタ。\r
36          * デフォルトの文字コード ISO-2022-JP がエンコーディングに使用されます。\r
37          * \r
38          * @param mimeMessage\r
39          */\r
40         public MimeMessageBuilder(MimeMessage mimeMessage) {\r
41                 this.mimeMessage = mimeMessage;\r
42         }\r
43 \r
44         /**\r
45          * コンストラクタ。\r
46          * 本文や件名のエンコーディングに使用する文字コードを指定します。\r
47          * \r
48          * @param mimeMessage\r
49          * @param charset エンコーディングに使用する文字コード\r
50          */\r
51         public MimeMessageBuilder(MimeMessage mimeMessage, String charset) {\r
52                 this.mimeMessage = mimeMessage;\r
53                 this.charset = charset;\r
54         }\r
55 \r
56         /**\r
57          * コンストラクタの引数で渡されたMimeMessageをそのまま返します。\r
58          * \r
59          * @return MimeMessage\r
60          */\r
61         public MimeMessage getMimeMessage() {\r
62                 return this.mimeMessage;\r
63         }\r
64 \r
65         /**\r
66          * 指定されたメールからMimeMessageを生成します。\r
67          * \r
68          * @param mail MimeMessageのソースとなるMail\r
69          * @throws MessagingException\r
70          * @throws UnsupportedEncodingException\r
71          */\r
72         public void buildMimeMessage(Mail mail) throws UnsupportedEncodingException, MessagingException {\r
73                 setCharset(mail);\r
74 \r
75                 setTo(mail);\r
76                 setCc(mail);\r
77                 setBcc(mail);\r
78                 // 宛先の指定がない場合エラー\r
79                 if (!hasRecipient) {\r
80                         throw new MessagingException("宛先の指定がありません。To、Cc、Bccのいずれか一つは指定する必要があります。");\r
81                 }\r
82                 setFrom(mail);\r
83                 setSubject(mail);\r
84                 setReplyTo(mail);\r
85                 setXHeaders(mail);\r
86                 setImportance(mail);\r
87 \r
88                 if (mail.isMultipartMail()) {\r
89 \r
90                         if (!mail.isFileAttached() && mail.isHtmlMail()) { // Plain text, HTML\r
91 \r
92                                 if (mail.getText() != null && mail.getText().length() > 0) { // Plain text, HTML\r
93 \r
94                                         MimeMultipart textAndHtmlMultipart = new MimeMultipart("alternative");\r
95                                         setPlainText(mail, textAndHtmlMultipart);\r
96                                         setHtmlText(mail, textAndHtmlMultipart);\r
97                                         this.mimeMessage.setContent(textAndHtmlMultipart);\r
98 \r
99                                 } else { // HTML Only マルチパートは使用しない\r
100 \r
101                                         setHtmlText(mail.getHtmlText(), this.mimeMessage);\r
102 \r
103                                 }\r
104 \r
105                         } else if (mail.isFileAttached() && mail.isHtmlMail()) { // Plain text, HMTL, File\r
106 \r
107                                 MimeMultipart textAndHtmlMultipart = new MimeMultipart("alternative");\r
108                                 setPlainText(mail, textAndHtmlMultipart);\r
109                                 setHtmlText(mail, textAndHtmlMultipart);\r
110 \r
111                                 MimeMultipart containingMultipart = new MimeMultipart();\r
112                                 MimeBodyPart textBodyPart = createMimeBodyPart(containingMultipart);\r
113                                 textBodyPart.setContent(textAndHtmlMultipart);\r
114                                 setAttachmentFiles(mail, containingMultipart);\r
115 \r
116                                 this.mimeMessage.setContent(containingMultipart);\r
117 \r
118                         } else if (mail.isFileAttached() && !mail.isHtmlMail()) { // Plain text, File\r
119 \r
120                                 MimeMultipart textAndFileMultipart = new MimeMultipart();\r
121                                 setPlainText(mail, textAndFileMultipart);\r
122                                 setAttachmentFiles(mail, textAndFileMultipart);\r
123                                 this.mimeMessage.setContent(textAndFileMultipart);\r
124 \r
125                         } else { // Plain text only マルチパートは使用しない\r
126 \r
127                                 setText(mail.getText(), this.mimeMessage);\r
128 \r
129                         }\r
130 \r
131                 } else {\r
132 \r
133                         setText(mail.getText(), this.mimeMessage);\r
134 \r
135                 }\r
136 \r
137         }\r
138 \r
139         /**\r
140          * メールに使用するcharsetを決定します。\r
141          * Mail#charsetが設定されている場合、その値が優先されます。\r
142          * \r
143          * @since 1.2.1\r
144          * @param mail\r
145          */\r
146         private void setCharset(Mail mail) {\r
147                 if (mail.getCharset() != null && !"".equals(mail.getCharset())) {\r
148                         charset = mail.getCharset();\r
149                 }\r
150         }\r
151 \r
152         /**\r
153          * \r
154          * @since 1.1\r
155          * \r
156          * @param mail\r
157          * @param mimeMultipart\r
158          * @throws MessagingException\r
159          * @throws UnsupportedEncodingException \r
160          */\r
161         private void setAttachmentFiles(Mail mail, MimeMultipart mimeMultipart)\r
162                                                                                                                                                         throws MessagingException,\r
163                                                                                                                                                         UnsupportedEncodingException {\r
164                 Mail.AttachmentFile[] files = mail.getAttachmentFiles();\r
165                 for (int i = 0; i < files.length; i++) {\r
166                         MimeBodyPart bodyPart = createMimeBodyPart(mimeMultipart);\r
167                         Mail.AttachmentFile attachmentFile = files[i];\r
168                         addAttachment(attachmentFile.getName(), attachmentFile.getDataSource(), bodyPart);\r
169                 }\r
170         }\r
171 \r
172         /**\r
173          * \r
174          * @since 1.1\r
175          * \r
176          * @param mail\r
177          * @param mimeMultipart\r
178          * @throws MessagingException \r
179          */\r
180         private void setHtmlText(Mail mail, MimeMultipart mimeMultipart) throws MessagingException {\r
181                 if (mail.isHtmlMail()) {\r
182                         MimeBodyPart bodyPart = createMimeBodyPart(mimeMultipart);\r
183                         setHtmlText(mail.getHtmlText(), bodyPart);\r
184                 }\r
185         }\r
186 \r
187         /**\r
188          * \r
189          * @since 1.1\r
190          * \r
191          * @param mail\r
192          * @param mimeMultipart\r
193          * @throws MessagingException \r
194          */\r
195         private void setPlainText(Mail mail, MimeMultipart mimeMultipart) throws MessagingException {\r
196                 if (mail.getText() != null && mail.getText().length() > 0) {\r
197                         MimeBodyPart bodyPart = createMimeBodyPart(mimeMultipart);\r
198                         setText(mail.getText(), bodyPart);\r
199                 }\r
200         }\r
201 \r
202         /**\r
203          * 新しいMimeBodyPartインスタンスを生成し、指定されたMimeMultipartに登録します。\r
204          * \r
205          * このメソッドはマルチパートメール生成時にのみ呼び出すことができます。\r
206          * プレーンテキストメール生成時には、mimeMulipartがnullなので、\r
207          * NullPointerExceptionがスローされます。\r
208          * \r
209          * @since 1.1\r
210          * \r
211          * @param mm\r
212          * @return 生成されたMimeBodyPart\r
213          * @throws MessagingException \r
214          */\r
215         private MimeBodyPart createMimeBodyPart(MimeMultipart mm) throws MessagingException {\r
216                 MimeBodyPart bodyPart = new MimeBodyPart();\r
217                 mm.addBodyPart(bodyPart);\r
218                 return bodyPart;\r
219         }\r
220 \r
221         /**\r
222          * @since 1.1\r
223          * \r
224          * @param htmlText\r
225          * @param mimePart \r
226          * @throws MessagingException\r
227          */\r
228         private void setHtmlText(final String htmlText, MimePart mimePart) throws MessagingException {\r
229                 if (charset != null) {\r
230                         mimePart.setContent(htmlText, "text/html; charset=" + charset);\r
231                 } else {\r
232                         mimePart.setContent(htmlText, "text/html");\r
233                 }\r
234                 setContentTransferEncoding(mimePart);\r
235         }\r
236 \r
237         /**\r
238          * @param mail \r
239          * @throws MessagingException\r
240          */\r
241         private void setXHeaders(Mail mail) throws MessagingException {\r
242                 Map headers = mail.getHeaders();\r
243                 if (headers == null) {\r
244                         return;\r
245                 }\r
246 \r
247                 Iterator itr = headers.keySet().iterator();\r
248                 while (itr.hasNext()) {\r
249                         String key = (String)itr.next();\r
250                         String value = (String)headers.get(key);\r
251                         mimeMessage.setHeader(key, value);\r
252                 }\r
253         }\r
254 \r
255         /**\r
256          * @param mail \r
257          * @throws MessagingException\r
258          */\r
259         private void setImportance(Mail mail) throws MessagingException {\r
260                 if (mail.getImportance() != null) {\r
261                         mimeMessage.setHeader("Importance", mail.getImportance());\r
262 \r
263                         int level = 3;\r
264                         if (Mail.Importance.HIGH.equals(mail.getImportance())) {\r
265                                 level = 1;\r
266                         } else if (Mail.Importance.LOW.equals(mail.getImportance())) {\r
267                                 level = 5;\r
268                         }\r
269                         mimeMessage.setHeader("X-Priority", String.valueOf(level));\r
270                 }\r
271         }\r
272 \r
273         /**\r
274          * @param mail \r
275          * @throws MessagingException\r
276          * @throws UnsupportedEncodingException \r
277          */\r
278         private void setReplyTo(Mail mail) throws MessagingException, UnsupportedEncodingException {\r
279                 if (mail.getReplyTo() != null) {\r
280                         mimeMessage.setReplyTo(new InternetAddress[] { convertCharset(mail.getReplyTo()) });\r
281                 }\r
282         }\r
283 \r
284         /**\r
285          * @param mail \r
286          * @throws MessagingException\r
287          * @throws UnsupportedEncodingException \r
288          */\r
289         private void setBcc(Mail mail) throws MessagingException, UnsupportedEncodingException {\r
290                 if (mail.getBcc().length > 0) {\r
291                         mimeMessage.setRecipients(MimeMessage.RecipientType.BCC, convertCharset(mail.getBcc()));\r
292                         hasRecipient = true;\r
293                 }\r
294         }\r
295 \r
296         /**\r
297          * @param mail \r
298          * @throws MessagingException\r
299          * @throws UnsupportedEncodingException \r
300          */\r
301         private void setCc(Mail mail) throws MessagingException, UnsupportedEncodingException {\r
302                 if (mail.getCc().length > 0) {\r
303                         mimeMessage.setRecipients(MimeMessage.RecipientType.CC, convertCharset(mail.getCc()));\r
304                         hasRecipient = true;\r
305                 }\r
306         }\r
307 \r
308         /**\r
309          * @param mail \r
310          * @throws MessagingException\r
311          * @throws UnsupportedEncodingException \r
312          */\r
313         private void setTo(Mail mail) throws MessagingException, UnsupportedEncodingException {\r
314                 if (mail.getTo().length > 0) {\r
315                         mimeMessage.setRecipients(MimeMessage.RecipientType.TO, convertCharset(mail.getTo()));\r
316                         hasRecipient = true;\r
317                 }\r
318         }\r
319 \r
320         /**\r
321          * 本文をセット。\r
322          * <p>\r
323          * NOTE: 本文の最後に改行がないとMozilla系のメーラーで最終行の日本語が文字化けしてしまう為、\r
324          * message.setTextの引数で最後に\nを追加している。\r
325          * \r
326          * @since 1.1\r
327          * \r
328          * @param text 本文\r
329          * @param mimePart 本文をセットするMimePart \r
330          * @throws MessagingException\r
331          */\r
332         private void setText(String text, MimePart mimePart) throws MessagingException {\r
333                 if (charset != null) {\r
334                         if (charset.equalsIgnoreCase(Mail.JIS_CHARSET)) {\r
335                                 // Cp932クラスを使用して、怪しい記号を強制的にJIS変換\r
336                                 mimePart.setText(Cp932.toJIS(text) + "\n", charset);\r
337                         } else {\r
338                                 mimePart.setText(text + "\n", charset);\r
339                         }\r
340                 } else {\r
341                         mimePart.setText(text + "\n");\r
342                 }\r
343                 setContentTransferEncoding(mimePart);\r
344         }\r
345 \r
346         /**\r
347          * charsetに応じてContent-Trnasfer-Encodingを設定します。\r
348          * が、UTF-8の時に8bitになること以外分かりません。。。\r
349          * \r
350          * @since 1.2.1\r
351          * @param mimePart\r
352          * @throws MessagingException \r
353          */\r
354         private void setContentTransferEncoding(MimePart mimePart) throws MessagingException {\r
355                 String contentTransferEncoding = "7bit";\r
356                 if ("UTF-8".equalsIgnoreCase(charset)) {\r
357                         contentTransferEncoding = "8bit";\r
358                 }\r
359                 mimePart.setHeader("Content-Transfer-Encoding", contentTransferEncoding);\r
360         }\r
361 \r
362         /**\r
363          * @param mail\r
364          * @throws MessagingException\r
365          * @throws UnsupportedEncodingException\r
366          */\r
367         private void setSubject(Mail mail) throws UnsupportedEncodingException, MessagingException {\r
368                 if (charset != null) {\r
369                         if (Mail.JIS_CHARSET.equalsIgnoreCase(charset)) {\r
370                                 String subject = Cp932.toJIS(mail.getSubject());\r
371                                 mimeMessage.setSubject(MimeUtility.encodeText(subject, charset, "B"));\r
372                         } else {\r
373                                 mimeMessage.setSubject(mail.getSubject(), charset);\r
374                         }\r
375                 } else {\r
376                         mimeMessage.setSubject(mail.getSubject());\r
377                 }\r
378         }\r
379 \r
380         /**\r
381          * @param mail\r
382          * @throws MessagingException \r
383          * @throws UnsupportedEncodingException \r
384          */\r
385         private void setFrom(Mail mail) throws MessagingException, UnsupportedEncodingException {\r
386                 InternetAddress address = convertCharset(mail.getFrom());\r
387                 mimeMessage.setFrom(address);\r
388         }\r
389 \r
390         private InternetAddress convertCharset(InternetAddress address)\r
391                                                                                                                                         throws UnsupportedEncodingException {\r
392                 String name = address.getPersonal();\r
393                 if (name != null && !"".equals(name) && Mail.JIS_CHARSET.equalsIgnoreCase(charset)) {\r
394                         name = Cp932.toJIS(name);\r
395                 }\r
396                 return new InternetAddress(address.getAddress(), name, charset);\r
397         }\r
398 \r
399         private InternetAddress[] convertCharset(InternetAddress[] addresses)\r
400                                                                                                                                                         throws UnsupportedEncodingException {\r
401                 for (int i = 0; i < addresses.length; i++) {\r
402                         addresses[i] = convertCharset(addresses[i]);\r
403                 }\r
404                 return addresses;\r
405         }\r
406 \r
407         /**\r
408          * 添付ファイルデータを指定されたMimeBodyPartにセットします。\r
409          * \r
410          * @since 1.1\r
411          * \r
412          * @param fileName\r
413          * @param dataSource\r
414          * @param mimeBodyPart ファイルデータをセットするMimeBodyPart\r
415          * @throws UnsupportedEncodingException\r
416          * @throws MessagingException\r
417          */\r
418         private void addAttachment(String fileName, DataSource dataSource, MimeBodyPart mimeBodyPart)\r
419                                                                                                                                                                                                         throws UnsupportedEncodingException,\r
420                                                                                                                                                                                                         MessagingException {\r
421                 if (charset != null) {\r
422                         // ファイル名のエンコード\r
423                         mimeBodyPart.setFileName(MimeUtility.encodeText(fileName, charset, "B"));\r
424                 } else {\r
425                         mimeBodyPart.setFileName(fileName);\r
426                 }\r
427 \r
428                 mimeBodyPart.setDataHandler(new DataHandler(dataSource));\r
429         }\r
430 \r
431 }