View Javadoc

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