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