View Javadoc

1   package com.ozacc.mail.fetch;
2   
3   import java.io.File;
4   import java.util.ArrayList;
5   import java.util.Date;
6   import java.util.Iterator;
7   import java.util.List;
8   
9   import javax.mail.Flags;
10  import javax.mail.MessagingException;
11  import javax.mail.internet.MimeMessage;
12  
13  import com.ozacc.mail.Mail;
14  
15  /***
16   * 受信メール。
17   * <p>
18   * <code>FetchMail</code>、<code>FetchMailPro</code>の実装クラスで受信したメールが、
19   * インターネットメールとしての仕様を満たしていないヘッダ(FromやToなど)の値がセットされていた場合、
20   * そのヘッダに該当する<code>ReceivedMail</code>インスタンスのプロパティには何もセットされません。
21   * 
22   * @since 1.2
23   * @author Tomohiro Otsuka
24   * @version $Id: ReceivedMail.java,v 1.1.2.8 2005/01/22 12:23:14 otsuka Exp $
25   */
26  public class ReceivedMail extends Mail {
27  
28  	private String replySubjectPrefix = "Re: ";
29  
30  	private Date date;
31  
32  	private String messageId;
33  
34  	private int size;
35  
36  	private List receivedHeaders;
37  
38  	private MimeMessage message;
39  
40  	/***
41  	 * コンストラクタ。
42  	 */
43  	public ReceivedMail() {
44  		super();
45  	}
46  
47  	/***
48  	 * コンストラクタ。
49  	 * 
50  	 * @param charset 
51  	 */
52  	public ReceivedMail(String charset) {
53  		super(charset);
54  	}
55  
56  	/***
57  	 * コピーコンストラクタ。
58  	 * 
59  	 * @param original 
60  	 */
61  	public ReceivedMail(Mail original) {
62  		super(original);
63  	}
64  
65  	/***
66  	 * 送信日時を返します。
67  	 * <p>
68  	 * 注: メールの受信日時ではありません。
69  	 * 
70  	 * @return 送信日時
71  	 */
72  	public Date getDate() {
73  		return date;
74  	}
75  
76  	/***
77  	 * 送信日時をセットします。
78  	 * 
79  	 * @param date 送信日時
80  	 */
81  	public void setDate(Date date) {
82  		this.date = date;
83  	}
84  
85  	/***
86  	 * 前後に&lt;&gt;が付いたメッセージIDを返します。
87  	 * 
88  	 * @return 前後に&lt;&gt;が付いたメッセージID
89  	 */
90  	public String getMessageId() {
91  		if (messageId.startsWith("<") && messageId.endsWith(">")) {
92  			return messageId;
93  		}
94  		return "<" + messageId + ">";
95  	}
96  
97  	/***
98  	 * メッセージIDを返します。前後に&lt;&gt;は付きません。
99  	 * 
100 	 * @return メッセージID
101 	 */
102 	public String getMessageIdOnly() {
103 		if (messageId.startsWith("<") && messageId.endsWith(">")) {
104 			return messageId.substring(1, messageId.length() - 1);
105 		}
106 		return messageId;
107 	}
108 
109 	/***
110 	 * メッセージIDをセットします。
111 	 * 
112 	 * @param messageId メッセージID
113 	 */
114 	public void setMessageId(String messageId) {
115 		this.messageId = messageId;
116 	}
117 
118 	/***
119 	 * @return Returns the inReplyTo.
120 	 */
121 	public String getInReplyTo() {
122 		return (String)headers.get("In-Reply-To");
123 	}
124 
125 	/***
126 	 * @return Returns the refereces.
127 	 */
128 	public String getRefereces() {
129 		return (String)headers.get("References");
130 	}
131 
132 	/***
133 	 * @return 返信時の件名に付ける接頭辞
134 	 */
135 	public String getReplySubjectPrefix() {
136 		return replySubjectPrefix;
137 	}
138 
139 	/***
140 	 * 返信時の件名に付ける接頭辞をセットします。
141 	 * デフォルトは「Re: 」。
142 	 * 
143 	 * @param replySubjectPrefix 返信時の件名に付ける接頭辞
144 	 */
145 	public void setReplySubjectPrefix(String replySubjectPrefix) {
146 		this.replySubjectPrefix = replySubjectPrefix;
147 	}
148 
149 	/***
150 	 * メール内容を出力します。<br>
151 	 * メールのソースに似たフォーマットで出力されます。
152 	 * 
153 	 * @see java.lang.Object#toString()
154 	 */
155 	public String toString() {
156 		StringBuffer buf = new StringBuffer(1000);
157 		buf.append("Mail\n");
158 		buf.append("Return-Path: ").append(returnPath).append("\n");
159 		buf.append("Message-ID: ").append(messageId).append("\n");
160 		buf.append("Date: ").append(date).append("\n");
161 		buf.append("From: ").append(from != null ? from.toUnicodeString() : null).append("\n");
162 		buf.append("To: ").append(arrayToCommaDelimitedString(to)).append("\n");
163 		buf.append("Cc: ").append(arrayToCommaDelimitedString(cc)).append("\n");
164 		buf.append("Bcc: ").append(arrayToCommaDelimitedString(bcc)).append("\n");
165 		buf.append("Reply-To: ").append(replyTo != null ? replyTo.toUnicodeString() : null).append(
166 				"\n");
167 		buf.append("Subject: ").append(subject).append("\n");
168 
169 		if (headers != null) {
170 			for (Iterator itr = headers.keySet().iterator(); itr.hasNext();) {
171 				String header = (String)itr.next();
172 				String value = (String)headers.get(header);
173 				buf.append(header).append(": ").append(value).append("\n");
174 			}
175 		}
176 
177 		buf.append("\n");
178 		buf.append(text);
179 
180 		if (htmlText != null) {
181 			buf.append("\n\n-----\n\n");
182 			buf.append(htmlText);
183 		}
184 
185 		if (isFileAttached()) {
186 			buf.append("\n\nAttachments\n");
187 			for (int i = 0, num = attachmentFiles.size(); i < num; i++) {
188 				AttachmentFile f = (AttachmentFile)attachmentFiles.get(i);
189 				buf.append("[").append(i + 1).append("] ").append(f.getName()).append("\n");
190 			}
191 		}
192 
193 		return buf.toString();
194 	}
195 
196 	/***
197 	 * @return Returns the message.
198 	 */
199 	public MimeMessage getMessage() {
200 		return message;
201 	}
202 
203 	/***
204 	 * @param message The message to set.
205 	 */
206 	public void setMessage(MimeMessage message) {
207 		this.message = message;
208 	}
209 
210 	/***
211 	 * メールサーバとの接続切断時に、このメールをメールサーバから削除します。
212 	 * 削除できるように設定ができた場合に true を返します。
213 	 * <p>
214 	 * このメソッドは、<code>FetchMailPro</code>のメソッドによって取得された
215 	 * <code>ReceivedMail</code>インスタンスでのみ有効です。
216 	 * また、<code>FetchMailPro</code>インスタンスがメールサーバに
217 	 * 接続されている状態での呼び出しのみ有効です。<br>
218 	 * これらの条件が満たされない時にこのメソッドが呼び出された場合
219 	 * false を返します。
220 	 * 
221 	 * TODO: うまく動いてない。
222 	 * 
223 	 * @see FetchMailPro
224 	 * @param delete 削除するように設定する場合 true
225 	 * @return 削除設定が正常に行われた場合 true
226 	 */
227 	public boolean setDelete(boolean delete) {
228 		if (message != null) {
229 			try {
230 				message.setFlag(Flags.Flag.DELETED, delete);
231 			} catch (MessagingException e) {
232 				return false;
233 			}
234 			return true;
235 		}
236 		return false;
237 	}
238 
239 	/***
240 	 * メールのサイズ(容量)を返します。単位はbyte。
241 	 * この値は厳密なものではないので注意してください。
242 	 * 
243 	 * @see MimeMessage#getSize()
244 	 * @return メールのサイズ(単位はbyte)
245 	 */
246 	public int getSize() {
247 		return size;
248 	}
249 
250 	/***
251 	 * メールのサイズ(容量)をセットします。単位はbyte。
252 	 * 
253 	 * @param size メールのサイズ(単位はbyte)
254 	 */
255 	public void setSize(int size) {
256 		this.size = size;
257 	}
258 
259 	/***
260 	 * 添付ファイルのFileインスタンス配列を返します。
261 	 * 添付ファイルがない場合は空の配列を返します。
262 	 * 
263 	 * @return 添付ファイルのFileインスタンス配列
264 	 */
265 	public File[] getFiles() {
266 		AttachmentFile[] aFiles = getAttachmentFiles();
267 		File[] files = new File[aFiles.length];
268 		for (int i = 0; i < aFiles.length; i++) {
269 			AttachmentFile aFile = aFiles[i];
270 			files[i] = aFile.getFile();
271 		}
272 		return files;
273 	}
274 
275 	/***
276 	 * このメールの返信メール用Mailインスタンスを生成して返します。
277 	 * <ul>
278 	 * <li>宛先(Toアドレス)には、このメールのReply-To、またはFromがセットされます。</li>
279 	 * <li>件名には、このメールの件名が大文字小文字問わず「Re:」で始まっていなければ、「Re: 」を頭に付けた件名がセットされます。「Re:」で始まっている場合には、その件名をそのままセットします。</li>
280 	 * <li>本文には、何もセットされません。</li>
281 	 * <li>このメールにMessage-IDがセットされていれば、In-Reply-Toヘッダにその値がセットされます。</li>
282 	 * <li>このメールにMessage-IDがセットされていれば、Referencesヘッダにその値が加えられます。</li>
283 	 * </ul>
284 	 * 
285 	 * @return 返信用のMailインスタンス
286 	 */
287 	public Mail reply() {
288 		Mail mail = new Mail();
289 
290 		// 宛先
291 		if (getReplyTo() != null) {
292 			mail.addTo(getReplyTo());
293 		} else {
294 			mail.addTo(getFrom());
295 		}
296 
297 		// 件名
298 		String subject = getSubject();
299 		if ((subject.length() >= 3 && !"Re:".equalsIgnoreCase(subject.substring(0, 3)))
300 				|| subject.length() < 3) {
301 			subject = replySubjectPrefix + subject;
302 		}
303 		mail.setSubject(subject);
304 
305 		// In-Reply-To, References
306 		String messageId = getMessageId();
307 		if (messageId != null && !"<>".equals(messageId)) {
308 			String references = getRefereces();
309 			if (references != null) {
310 				references = messageId + " " + references;
311 			} else if (getInReplyTo() != null) {
312 				references = messageId + " " + getInReplyTo();
313 			} else {
314 				references = messageId;
315 			}
316 			mail.addHeader("References", references);
317 			mail.addHeader("In-Reply-To", messageId);
318 		}
319 
320 		return mail;
321 	}
322 
323 	/***
324 	 * Receivedヘッダフィールドを追加します。
325 	 * 
326 	 * @param rh Receivedヘッダフィールド
327 	 */
328 	public void addReceviedHeader(ReceivedHeader rh) {
329 		if (receivedHeaders == null) {
330 			receivedHeaders = new ArrayList();
331 		}
332 		receivedHeaders.add(rh);
333 	}
334 
335 	/***
336 	 * Receivedヘッダフィールドの配列を返します。<br>
337 	 * 自分のサーバ(このメールが届いたサーバ)から送信元のメールサーバを辿る順で並んでいます。<br>
338 	 * 受信メールがReceivedヘッダフィールドを持たない、または解析できなかった場合は空の配列を返します。
339 	 * 
340 	 * @return Receivedヘッダフィールドの配列
341 	 */
342 	public ReceivedHeader[] getReceivedHeaders() {
343 		if (receivedHeaders == null) {
344 			return new ReceivedHeader[0];
345 		}
346 		return (ReceivedHeader[])receivedHeaders
347 				.toArray(new ReceivedHeader[receivedHeaders.size()]);
348 	}
349 
350 	/***
351 	 * Receviedヘッダフィールドを表すクラス。
352 	 */
353 	public static class ReceivedHeader {
354 
355 		private String from;
356 
357 		private String by;
358 
359 		/***
360 		 * @param from メールを送信したサーバのホスト名
361 		 * @param by メールを受信したサーバのホスト名
362 		 */
363 		public ReceivedHeader(String from, String by) {
364 			this.from = from;
365 			this.by = by;
366 		}
367 
368 		/***
369 		 * @see java.lang.Object#toString()
370 		 */
371 		public String toString() {
372 			return "Sent from " + from + " and received by " + by;
373 		}
374 
375 		/***
376 		 * @return メールを受信したサーバのホスト名
377 		 */
378 		public String getBy() {
379 			return by;
380 		}
381 
382 		/***
383 		 * @return メールを送信したサーバのホスト名
384 		 */
385 		public String getFrom() {
386 			return from;
387 		}
388 	}
389 }