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 }