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.9 2005/01/23 07:13:13 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 getMessageIdWithoutBracket() {
    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 	 * In-Reply-Toヘッダの値を返します。
    120 	 * In-Reply-Toヘッダがない場合はnullを返します。
    121 	 *
    122 	 * @return In-Reply-Toヘッダの値
    123 	 */
    124 	public String getInReplyTo() {
    125 		return (String)headers.get("In-Reply-To");
    126 	}
    127
    128 	/***
    129 	 * Referencesヘッダの値を返します。
    130 	 * Referencesヘッダがない場合はnullを返します。
    131 	 *
    132 	 * @return Referencesヘッダの値
    133 	 */
    134 	public String getRefereces() {
    135 		return (String)headers.get("References");
    136 	}
    137
    138 	/***
    139 	 * @return 返信時の件名に付ける接頭辞
    140 	 */
    141 	public String getReplySubjectPrefix() {
    142 		return replySubjectPrefix;
    143 	}
    144
    145 	/***
    146 	 * 返信時の件名に付ける接頭辞をセットします。
    147 	 * デフォルトは「Re: 」。
    148 	 *
    149 	 * @param replySubjectPrefix 返信時の件名に付ける接頭辞
    150 	 */
    151 	public void setReplySubjectPrefix(String replySubjectPrefix) {
    152 		this.replySubjectPrefix = replySubjectPrefix;
    153 	}
    154
    155 	/***
    156 	 * メール内容を出力します。<br>
    157 	 * メールのソースに似たフォーマットで出力されます。
    158 	 *
    159 	 * @see java.lang.Object#toString()
    160 	 */
    161 	public String toString() {
    162 		StringBuffer buf = new StringBuffer(1000);
    163 		buf.append("Mail\n");
    164 		buf.append("Return-Path: ").append(returnPath).append("\n");
    165 		buf.append("Message-ID: ").append(messageId).append("\n");
    166 		buf.append("Date: ").append(date).append("\n");
    167 		buf.append("From: ").append(from != null ? from.toUnicodeString() : null).append("\n");
    168 		buf.append("To: ").append(arrayToCommaDelimitedString(to)).append("\n");
    169 		buf.append("Cc: ").append(arrayToCommaDelimitedString(cc)).append("\n");
    170 		buf.append("Bcc: ").append(arrayToCommaDelimitedString(bcc)).append("\n");
    171 		buf.append("Reply-To: ").append(replyTo != null ? replyTo.toUnicodeString() : null).append(
    172 				"\n");
    173 		buf.append("Subject: ").append(subject).append("\n");
    174
    175 		if (headers != null) {
    176 			for (Iterator itr = headers.keySet().iterator(); itr.hasNext();) {
    177 				String header = (String)itr.next();
    178 				String value = (String)headers.get(header);
    179 				buf.append(header).append(": ").append(value).append("\n");
    180 			}
    181 		}
    182
    183 		buf.append("\n");
    184 		buf.append(text);
    185
    186 		if (htmlText != null) {
    187 			buf.append("\n\n-----\n\n");
    188 			buf.append(htmlText);
    189 		}
    190
    191 		if (isFileAttached()) {
    192 			buf.append("\n\nAttachments\n");
    193 			for (int i = 0, num = attachmentFiles.size(); i < num; i++) {
    194 				AttachmentFile f = (AttachmentFile)attachmentFiles.get(i);
    195 				buf.append("[").append(i + 1).append("] ").append(f.getName()).append("\n");
    196 			}
    197 		}
    198
    199 		return buf.toString();
    200 	}
    201
    202 	/***
    203 	 * @return Returns the message.
    204 	 */
    205 	public MimeMessage getMessage() {
    206 		return message;
    207 	}
    208
    209 	/***
    210 	 * @param message The message to set.
    211 	 */
    212 	public void setMessage(MimeMessage message) {
    213 		this.message = message;
    214 	}
    215
    216 	/***
    217 	 * メールサーバとの接続切断時に、このメールをメールサーバから削除します。
    218 	 * 削除できるように設定ができた場合に true を返します。
    219 	 * <p>
    220 	 * このメソッドは、<code>FetchMailPro</code>のメソッドによって取得された
    221 	 * <code>ReceivedMail</code>インスタンスでのみ有効です。
    222 	 * また、<code>FetchMailPro</code>インスタンスがメールサーバに
    223 	 * 接続されている状態での呼び出しのみ有効です。<br>
    224 	 * これらの条件が満たされない時にこのメソッドが呼び出された場合
    225 	 * false を返します。
    226 	 *
    227 	 * TODO: うまく動いてない。
    228 	 *
    229 	 * @see FetchMailPro
    230 	 * @param delete 削除するように設定する場合 true
    231 	 * @return 削除設定が正常に行われた場合 true
    232 	 */
    233 	public boolean setDelete(boolean delete) {
    234 		if (message != null) {
    235 			try {
    236 				message.setFlag(Flags.Flag.DELETED, delete);
    237 			} catch (MessagingException e) {
    238 				return false;
    239 			}
    240 			return true;
    241 		}
    242 		return false;
    243 	}
    244
    245 	/***
    246 	 * メールのサイズ(容量)を返します。単位はbyte。
    247 	 * この値は厳密なものではないので注意してください。
    248 	 *
    249 	 * @see MimeMessage#getSize()
    250 	 * @return メールのサイズ(単位はbyte)
    251 	 */
    252 	public int getSize() {
    253 		return size;
    254 	}
    255
    256 	/***
    257 	 * メールのサイズ(容量)をセットします。単位はbyte。
    258 	 *
    259 	 * @param size メールのサイズ(単位はbyte)
    260 	 */
    261 	public void setSize(int size) {
    262 		this.size = size;
    263 	}
    264
    265 	/***
    266 	 * 添付ファイルのFileインスタンス配列を返します。
    267 	 * 添付ファイルがない場合は空の配列を返します。
    268 	 *
    269 	 * @return 添付ファイルのFileインスタンス配列
    270 	 */
    271 	public File[] getFiles() {
    272 		AttachmentFile[] aFiles = getAttachmentFiles();
    273 		File[] files = new File[aFiles.length];
    274 		for (int i = 0; i < aFiles.length; i++) {
    275 			AttachmentFile aFile = aFiles[i];
    276 			files[i] = aFile.getFile();
    277 		}
    278 		return files;
    279 	}
    280
    281 	/***
    282 	 * このメールの返信メール用Mailインスタンスを生成して返します。
    283 	 * <ul>
    284 	 * <li>宛先(Toアドレス)には、このメールのReply-To、またはFromがセットされます。</li>
    285 	 * <li>件名には、このメールの件名が大文字小文字問わず「Re:」で始まっていなければ、「Re: 」を頭に付けた件名がセットされます。「Re:」で始まっている場合には、その件名をそのままセットします。</li>
    286 	 * <li>本文には、何もセットされません。</li>
    287 	 * <li>このメールにMessage-IDがセットされていれば、In-Reply-Toヘッダにその値がセットされます。</li>
    288 	 * <li>このメールにMessage-IDがセットされていれば、Referencesヘッダにその値が加えられます。</li>
    289 	 * </ul>
    290 	 *
    291 	 * @return 返信用のMailインスタンス
    292 	 */
    293 	public Mail reply() {
    294 		Mail mail = new Mail();
    295
    296 		// 宛先
    297 		if (getReplyTo() != null) {
    298 			mail.addTo(getReplyTo());
    299 		} else {
    300 			mail.addTo(getFrom());
    301 		}
    302
    303 		// 件名
    304 		String subject = getSubject();
    305 		if ((subject.length() >= 3 && !"Re:".equalsIgnoreCase(subject.substring(0, 3)))
    306 				|| subject.length() < 3) {
    307 			subject = replySubjectPrefix + subject;
    308 		}
    309 		mail.setSubject(subject);
    310
    311 		// In-Reply-To, References
    312 		String messageId = getMessageId();
    313 		if (messageId != null && !"<>".equals(messageId)) {
    314 			String references = getRefereces();
    315 			if (references != null) {
    316 				references = messageId + " " + references;
    317 			} else if (getInReplyTo() != null) {
    318 				references = messageId + " " + getInReplyTo();
    319 			} else {
    320 				references = messageId;
    321 			}
    322 			mail.addHeader("References", references);
    323 			mail.addHeader("In-Reply-To", messageId);
    324 		}
    325
    326 		return mail;
    327 	}
    328
    329 	/***
    330 	 * Receivedヘッダフィールドを追加します。
    331 	 *
    332 	 * @param rh Receivedヘッダフィールド
    333 	 */
    334 	public void addReceviedHeader(ReceivedHeader rh) {
    335 		if (receivedHeaders == null) {
    336 			receivedHeaders = new ArrayList();
    337 		}
    338 		receivedHeaders.add(rh);
    339 	}
    340
    341 	/***
    342 	 * Receivedヘッダフィールドの配列を返します。<br>
    343 	 * 自分のサーバ(このメールが届いたサーバ)から送信元のメールサーバを辿る順で並んでいます。<br>
    344 	 * 受信メールがReceivedヘッダフィールドを持たない、または解析できなかった場合は空の配列を返します。
    345 	 *
    346 	 * @return Receivedヘッダフィールドの配列
    347 	 */
    348 	public ReceivedHeader[] getReceivedHeaders() {
    349 		if (receivedHeaders == null) {
    350 			return new ReceivedHeader[0];
    351 		}
    352 		return (ReceivedHeader[])receivedHeaders
    353 				.toArray(new ReceivedHeader[receivedHeaders.size()]);
    354 	}
    355
    356 	/***
    357 	 * Receviedヘッダフィールドを表すクラス。
    358 	 */
    359 	public static class ReceivedHeader {
    360
    361 		private String from;
    362
    363 		private String by;
    364
    365 		/***
    366 		 * @param from メールを送信したサーバのホスト名
    367 		 * @param by メールを受信したサーバのホスト名
    368 		 */
    369 		public ReceivedHeader(String from, String by) {
    370 			this.from = from;
    371 			this.by = by;
    372 		}
    373
    374 		/***
    375 		 * @see java.lang.Object#toString()
    376 		 */
    377 		public String toString() {
    378 			return "Sent from " + from + " and received by " + by;
    379 		}
    380
    381 		/***
    382 		 * メールを受信したサーバのホスト名を返します。
    383 		 *
    384 		 * @return メールを受信したサーバのホスト名
    385 		 */
    386 		public String getBy() {
    387 			return by;
    388 		}
    389
    390 		/***
    391 		 * メールを送信したサーバのホスト名を返します。
    392 		 *
    393 		 * @return メールを送信したサーバのホスト名
    394 		 */
    395 		public String getFrom() {
    396 			return from;
    397 		}
    398 	}
    399 }