Coverage report

  %line %branch
com.ozacc.mail.impl.SendMailProImpl
15% 
75% 

 1  
 package com.ozacc.mail.impl;
 2  
 
 3  
 import java.io.UnsupportedEncodingException;
 4  
 import java.util.Date;
 5  
 import java.util.Properties;
 6  
 
 7  
 import javax.mail.Address;
 8  
 import javax.mail.AuthenticationFailedException;
 9  
 import javax.mail.MessagingException;
 10  
 import javax.mail.Session;
 11  
 import javax.mail.Transport;
 12  
 import javax.mail.internet.MimeMessage;
 13  
 
 14  
 import org.apache.commons.logging.Log;
 15  
 import org.apache.commons.logging.LogFactory;
 16  
 
 17  
 import com.ozacc.mail.Mail;
 18  
 import com.ozacc.mail.MailAuthenticationException;
 19  
 import com.ozacc.mail.MailBuildException;
 20  
 import com.ozacc.mail.MailException;
 21  
 import com.ozacc.mail.MailSendException;
 22  
 import com.ozacc.mail.NotConnectedException;
 23  
 import com.ozacc.mail.SendMailPro;
 24  
 
 25  
 /**
 26  
  * SendMailProインターフェースの実装クラス。
 27  
  * 
 28  
  * @since 1.0
 29  
  * @author Tomohiro Otsuka
 30  
  * @version $Id: SendMailProImpl.java,v 1.4.2.3 2005/01/29 23:09:36 otsuka Exp $
 31  
  */
 32  1
 public class SendMailProImpl implements SendMailPro {
 33  
 
 34  
 	/** smtp */
 35  
 	public static final String DEFAULT_PROTOCOL = "smtp";
 36  
 
 37  
 	/** -1 */
 38  
 	public static final int DEFAULT_PORT = -1;
 39  
 
 40  
 	/** localhost */
 41  
 	public static final String DEFAULT_HOST = "localhost";
 42  
 
 43  
 	/** ISO-2022-JP */
 44  
 	public static final String JIS_CHARSET = "ISO-2022-JP";
 45  
 
 46  
 	private static final String RETURN_PATH_KEY = "mail.smtp.from";
 47  
 
 48  1
 	private static Log log = LogFactory.getLog(SendMailProImpl.class);
 49  
 
 50  
 	/** 接続タイムアウト */
 51  
 	private static final int DEFAULT_CONNECTION_TIMEOUT = 5000;
 52  
 
 53  
 	/** 読�?タイムアウト */
 54  
 	private static final int DEFAULT_READ_TIMEOUT = 5000;
 55  
 
 56  1
 	private String protocol = DEFAULT_PROTOCOL;
 57  
 
 58  1
 	private String host = DEFAULT_HOST;
 59  
 
 60  1
 	private int port = DEFAULT_PORT;
 61  
 
 62  
 	private String username;
 63  
 
 64  
 	private String password;
 65  
 
 66  1
 	private String charset = JIS_CHARSET;
 67  
 
 68  
 	private String returnPath;
 69  
 
 70  
 	private Session session;
 71  
 
 72  
 	private Transport transport;
 73  
 
 74  
 	private boolean connected;
 75  
 
 76  
 	private String messageId;
 77  
 
 78  1
 	private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
 79  
 
 80  1
 	private int readTimeout = DEFAULT_READ_TIMEOUT;
 81  
 
 82  
 	/**
 83  
 	 * コンストラクタ。
 84  
 	 */
 85  2
 	public SendMailProImpl() {}
 86  
 
 87  
 	/**
 88  
 	 * コンストラクタ。使用す�?SMTPサーバを指定します。
 89  
 	 * 
 90  
 	 * @param host SMTPサーバのホスト名、またはIPアド�?ス
 91  
 	 */
 92  
 	public SendMailProImpl(String host) {
 93  1
 		this();
 94  1
 		setHost(host);
 95  1
 	}
 96  
 
 97  
 	/**
 98  
 	 * @see com.ozacc.mail.SendMailPro#connect()
 99  
 	 */
 100  
 	public synchronized void connect() throws MailException {
 101  0
 		if (session == null) {
 102  0
 			initSession();
 103  
 		}
 104  
 
 105  
 		// グ��充バ�?Return-Pathの設�?
 106  0
 		putOnReturnPath(this.returnPath);
 107  
 
 108  
 		try {
 109  
 			// SMTPサーバに接続
 110  0
 			log.debug("SMTPサーバ[" + host + "]に接続します。");
 111  
 
 112  0
 			transport = session.getTransport(protocol);
 113  0
 			transport.connect(host, port, username, password);
 114  0
 		} catch (AuthenticationFailedException ex) {
 115  0
 			log.error("SMTPサーバ[" + host + "]への接続認証に失敗しました。", ex);
 116  0
 			throw new MailAuthenticationException(ex);
 117  0
 		} catch (MessagingException ex) {
 118  0
 			log.error("SMTPサーバ[" + host + "]への接続に失敗しました。", ex);
 119  0
 			throw new MailSendException("SMTPサーバ[" + host + "]への接続に失敗しました。", ex);
 120  
 		}
 121  
 
 122  0
 		log.debug("SMTPサーバ[" + host + "]に接続しました。");
 123  
 
 124  0
 		connected = true;
 125  0
 	}
 126  
 
 127  
 	/**
 128  
 	 * Sessionの初�?化を行います。
 129  
 	 * タイムアウト値を設定したPropertiesをセットします。
 130  
 	 */
 131  
 	private void initSession() {
 132  0
 		Properties prop = new Properties();
 133  
 		// タイムアウトの設�?
 134  0
 		prop.put("mail.smtp.connectiontimeout", String.valueOf(connectionTimeout));
 135  0
 		prop.put("mail.smtp.timeout", String.valueOf(readTimeout));
 136  0
 		session = Session.getInstance(prop);
 137  0
 	}
 138  
 
 139  
 	/**
 140  
 	 * @see com.ozacc.mail.SendMailPro#disconnect()
 141  
 	 */
 142  
 	public synchronized void disconnect() throws MailException {
 143  0
 		if (connected) {
 144  
 			try {
 145  0
 				log.debug("SMTPサーバ[" + host + "]との接続を切断します。");
 146  
 
 147  
 				// SMTPサーバとの接続を切断
 148  0
 				transport.close();
 149  0
 				connected = false;
 150  
 
 151  0
 				log.debug("SMTPサーバ[" + host + "]との接続を切断しました。");
 152  0
 			} catch (MessagingException ex) {
 153  0
 				log.error("SMTPサーバ[" + host + "]との接続切断に失敗しました。", ex);
 154  0
 				throw new MailException("SMTPサーバ[" + host + "]との接続切断に失敗しました。");
 155  0
 			} finally {
 156  
 				// グ��充バ�?Return-Pathの解�?
 157  0
 				releaseReturnPath(false);
 158  0
 			}
 159  
 		} else {
 160  0
 			log.warn("SMTPサーバ[" + host + "]との接続が確立さ�?ていない状態で、接続の切断が�?クエストさ�?ました。");
 161  
 		}
 162  0
 	}
 163  
 
 164  
 	/**
 165  
 	 * ReturnPathをセットします。
 166  
 	 * 
 167  
 	 * @param returnPath
 168  
 	 */
 169  
 	private void putOnReturnPath(String returnPath) {
 170  0
 		if (returnPath != null) {
 171  0
 			session.getProperties().put(RETURN_PATH_KEY, returnPath);
 172  0
 			log.debug("Return-Path[" + returnPath + "]を設定しました。");
 173  
 		}
 174  0
 	}
 175  
 
 176  
 	/**
 177  
 	 * ReturnPathの設定をク�?アします。
 178  
 	 * <p>
 179  
 	 * setGlobalReturnPathAgainがtrueに指定さ�?てい�?�?合、�?旦Return-Path設定をク�?アした後に、
 180  
 	 * グ��充バ�?なReturn-Path(setReturnPath()メソッドで、このインスタンスにセットさ�?たReturn-Pathアド�?ス)を設定します。
 181  
 	 * グ��充バ�?なReturn-Pathがセットさ�?ていなけ�?ばReturn-Pathはク�?アさ�?たままになります。
 182  
 	 * <p>
 183  
 	 * ク�?アさ�?た状態でsend()メソッドが実行さ�?�?と、Fromの値がReturn-Pathに使用さ�?ます。
 184  
 	 * 
 185  
 	 * @param setGlobalReturnPathAgain Return-Path設定をク�?アした後、再度グ��充バ�?なReturn-Pathをセットす�?�?�? true
 186  
 	 */
 187  
 	private void releaseReturnPath(boolean setGlobalReturnPathAgain) {
 188  0
 		session.getProperties().remove(RETURN_PATH_KEY);
 189  0
 		log.debug("Return-Path設定をク�?アしました。");
 190  
 
 191  0
 		if (setGlobalReturnPathAgain && this.returnPath != null) {
 192  0
 			putOnReturnPath(this.returnPath);
 193  
 		}
 194  0
 	}
 195  
 
 196  
 	/**
 197  
 	 * @see com.ozacc.mail.SendMailPro#send(javax.mail.internet.MimeMessage)
 198  
 	 */
 199  
 	public void send(MimeMessage mimeMessage) throws MailException {
 200  
 		Address[] addresses;
 201  
 		try {
 202  0
 			addresses = mimeMessage.getAllRecipients();
 203  0
 		} catch (MessagingException ex) {
 204  0
 			log.error("メー�?の送信に失敗しました。", ex);
 205  0
 			throw new MailSendException("メー�?の送信に失敗しました。", ex);
 206  
 		}
 207  0
 		processSend(mimeMessage, addresses);
 208  0
 	}
 209  
 
 210  
 	/**
 211  
 	 * @param mimeMessage 
 212  
 	 */
 213  
 	private void processSend(MimeMessage mimeMessage, Address[] addresses) {
 214  0
 		if (!connected) {
 215  0
 			log.error("SMTPサーバへの接続が確立さ�?ていません。");
 216  0
 			throw new NotConnectedException("SMTPサーバへの接続が確立さ�?ていません。");
 217  
 		}
 218  
 
 219  
 		try {
 220  
 			// 送信�?�?をセット
 221  0
 			mimeMessage.setSentDate(new Date());
 222  0
 			mimeMessage.saveChanges();
 223  
 			// 送信
 224  0
 			log.debug("メー�?を送信します。");
 225  0
 			transport.sendMessage(mimeMessage, addresses);
 226  0
 			log.debug("メー�?を送信しました。");
 227  0
 		} catch (MessagingException ex) {
 228  0
 			log.error("メー�?の送信に失敗しました。", ex);
 229  0
 			throw new MailSendException("メー�?の送信に失敗しました。", ex);
 230  
 		}
 231  0
 	}
 232  
 
 233  
 	/**
 234  
 	 * @see com.ozacc.mail.SendMailPro#send(com.ozacc.mail.Mail)
 235  
 	 */
 236  
 	public void send(Mail mail) throws MailException {
 237  0
 		if (mail.getReturnPath() != null) {
 238  0
 			sendMailWithReturnPath(mail);
 239  
 		} else {
 240  0
 			sendMail(mail);
 241  
 		}
 242  0
 	}
 243  
 
 244  
 	/**
 245  
 	 * 指定さ�?たMailからMimeMessageを生成し、send(MimeMessage)メソッドに渡します。
 246  
 	 * 
 247  
 	 * @param mail
 248  
 	 * @throws MailException
 249  
 	 */
 250  
 	private void sendMail(Mail mail) throws MailException {
 251  
 		// MimeMessageの生成
 252  0
 		MimeMessage message = createMimeMessage();
 253  0
 		MimeMessageBuilder builder = new MimeMessageBuilder(message, charset);
 254  
 		try {
 255  0
 			builder.buildMimeMessage(mail);
 256  0
 		} catch (UnsupportedEncodingException e) {
 257  0
 			throw new MailBuildException("サポートさ�?ていない文字コードが指定さ�?ました。", e);
 258  0
 		} catch (MessagingException e) {
 259  0
 			throw new MailBuildException("MimeMessageの生成に失敗しました。", e);
 260  
 		}
 261  
 		// 送信
 262  0
 		if (mail.getEnvelopeTo().length > 0) {
 263  0
 			log.debug("メー�?はenvelope-toアド�?スに送信さ�?ます。");
 264  0
 			processSend(message, mail.getEnvelopeTo());
 265  
 		} else {
 266  0
 			send(message);
 267  
 		}
 268  0
 	}
 269  
 
 270  
 	/**
 271  
 	 * 指定さ�?たMailにセットさ�?たReturn-Pathを設定して、メー�?を送信します。
 272  
 	 * 同�?メソッドです。
 273  
 	 * 
 274  
 	 * @param mail
 275  
 	 * @throws MailException
 276  
 	 */
 277  
 	private synchronized void sendMailWithReturnPath(Mail mail) throws MailException {
 278  0
 		putOnReturnPath(mail.getReturnPath().getAddress());
 279  
 
 280  0
 		sendMail(mail);
 281  
 
 282  0
 		releaseReturnPath(true);
 283  0
 	}
 284  
 
 285  
 	/**
 286  
 	 * 新しいMimeMessageオブジェクトを生成します。
 287  
 	 * 
 288  
 	 * @return 新しいMimeMessageオブジェクト
 289  
 	 */
 290  
 	public MimeMessage createMimeMessage() {
 291  0
 		if (isMessageIdCustomized()) {
 292  0
 			return new OMLMimeMessage(session, messageId);
 293  
 		}
 294  0
 		return new MimeMessage(session);
 295  
 	}
 296  
 
 297  
 	/**
 298  
 	 * Message-Idヘッダのドメイン部分を独自にセットしてい�?かどうか判定します。
 299  
 	 * 
 300  
 	 * @return Message-Idヘッダのドメイン部分を独自にセットしてい�?�?�? true
 301  
 	 */
 302  
 	private boolean isMessageIdCustomized() {
 303  0
 		return messageId != null;
 304  
 	}
 305  
 
 306  
 	/**
 307  
 	 * @return Sessionインスタンス
 308  
 	 */
 309  
 	protected Session getSession() {
 310  0
 		return session;
 311  
 	}
 312  
 
 313  
 	/**
 314  
 	 * エンコーディングに使用す�?文字コードを返します。
 315  
 	 * 
 316  
 	 * @return エンコーディングに使用す�?文字コード
 317  
 	 */
 318  
 	public String getCharset() {
 319  0
 		return charset;
 320  
 	}
 321  
 
 322  
 	/**
 323  
 	 * メー�?の�?名や本文のエンコーディングに使用す�?文字コードを指定します。
 324  
 	 * デフォ�?トは ISO-2022-JP です。
 325  
 	 * <p>
 326  
 	 * �?本�?環境で利用す�?�?合は通�?変更す�?必要はありません。
 327  
 	 * 
 328  
 	 * @param charset エンコーディングに使用す�?文字コード
 329  
 	 */
 330  
 	public void setCharset(String charset) {
 331  0
 		this.charset = charset;
 332  0
 	}
 333  
 
 334  
 	/**
 335  
 	 * @return Returns the host.
 336  
 	 */
 337  
 	public String getHost() {
 338  0
 		return host;
 339  
 	}
 340  
 
 341  
 	/**
 342  
 	 * SMTPサーバのホスト名、またはIPアド�?スをセットします。
 343  
 	 * デフォ�?トは localhost です。
 344  
 	 * 
 345  
 	 * @param host SMTPサーバのホスト名、またはIPアド�?ス
 346  
 	 */
 347  
 	public void setHost(String host) {
 348  1
 		this.host = host;
 349  1
 	}
 350  
 
 351  
 	/**
 352  
 	 * @return SMTPサーバ認証パス�?ード
 353  
 	 */
 354  
 	public String getPassword() {
 355  0
 		return password;
 356  
 	}
 357  
 
 358  
 	/**
 359  
 	 * SMTPサーバの接続認証が必要な�?合にパス�?ードをセットします。
 360  
 	 * 
 361  
 	 * @param password SMTPサーバ認証パス�?ード
 362  
 	 */
 363  
 	public void setPassword(String password) {
 364  0
 		this.password = password;
 365  0
 	}
 366  
 
 367  
 	/**
 368  
 	 * @return SMTPサーバのポート番�?
 369  
 	 */
 370  
 	public int getPort() {
 371  0
 		return port;
 372  
 	}
 373  
 
 374  
 	/**
 375  
 	 * SMTPサーバのポート番号をセットします。
 376  
 	 * 
 377  
 	 * @param port SMTPサーバのポート番�?
 378  
 	 */
 379  
 	public void setPort(int port) {
 380  0
 		this.port = port;
 381  0
 	}
 382  
 
 383  
 	/**
 384  
 	 * プ��組コ�?を返します。
 385  
 	 * 
 386  
 	 * @return プ��組コ�?
 387  
 	 */
 388  
 	public String getProtocol() {
 389  0
 		return protocol;
 390  
 	}
 391  
 
 392  
 	/**
 393  
 	 * プ��組コ�?をセットします。デフォ�?トは「smtp」。
 394  
 	 * 
 395  
 	 * @param protocol プ��組コ�?
 396  
 	 */
 397  
 	public void setProtocol(String protocol) {
 398  0
 		this.protocol = protocol;
 399  0
 	}
 400  
 
 401  
 	/**
 402  
 	 * @return Return-Pathアド�?ス
 403  
 	 */
 404  
 	public String getReturnPath() {
 405  0
 		return class="keyword">returnPath;
 406  
 	}
 407  
 
 408  
 	/**
 409  
 	 * Return-Pathアド�?スをセットします。
 410  
 	 * <p>
 411  
 	 * 送信す�?Mailインスタンスに指定さ�?たFromアド�?ス以外のアド�?スをReturn-Pathとしたい�?合に使用します。
 412  
 	 * ここでセットさ�?たReturn-Pathより、Mailインスタンスにセットさ�?たReturn-Pathが優先さ�?ます。
 413  
 	 * 
 414  
 	 * @param returnPath Return-Pathアド�?ス
 415  
 	 */
 416  
 	public void setReturnPath(String returnPath) {
 417  0
 		this.returnPath = returnPath;
 418  0
 	}
 419  
 
 420  
 	/**
 421  
 	 * @return SMTPサーバ認証ユーザ名
 422  
 	 */
 423  
 	public String getUsername() {
 424  0
 		return username;
 425  
 	}
 426  
 
 427  
 	/**
 428  
 	 * SMTPサーバの接続認証が必要な�?合にユーザ名をセットします。
 429  
 	 * 
 430  
 	 * @param username SMTPサーバ認証ユーザ名
 431  
 	 */
 432  
 	public void setUsername(String username) {
 433  0
 		this.username = username;
 434  0
 	}
 435  
 
 436  
 	/**
 437  
 	 * 生成さ�?�?MimeMessageに付けら�?�?Message-Idヘッダのドメイン部分を指定します。<br>
 438  
 	 * 指定さ�?ない�?�?(nullや空文字列の�?�?)は、JavaMailがMessage-Idヘッダを生成します。
 439  
 	 * JavaMailが生成す�?「JavaMail.実行ユーザ名@ホスト名」のMessage-Idを避けたい�?合に、このメソッドを使用します。
 440  
 	 * <p>
 441  
 	 * messageIdプ��叢ティがセットさ�?てい�?�?合、Mailから生成さ�?�?MimeMessageのMessage-Idには
 442  
 	 * <code>タイムスタンプ + ランダムに生成さ�?�?16桁の数値 + ここでセットさ�?た値</code>
 443  
 	 * が使用さ�?ます。
 444  
 	 * <p>
 445  
 	 * 生成さ�?�?Message-Idの例。 (実際の数値部分は送信メー�?毎に変�?ります)<ul>
 446  
 	 * <li>messageIdに'example.com'を指定した�?合・・・1095714924963.5619528074501343@example.com</li>
 447  
 	 * <li>messageIdに'@example.com'を指定した�?合・・・1095714924963.5619528074501343@example.com (上と同じ)</li>
 448  
 	 * <li>messageIdに'OML@example.com'を指定した�?合・・・1095714924963.5619528074501343.OML@example.com</li>
 449  
 	 * <li>messageIdに'.OML@example.com'を指定した�?合・・・1095714924963.5619528074501343.OML@example.com (上と同じ)</li>
 450  
 	 * </ul>
 451  
 	 * <p>
 452  
 	 * <strong>�?:</strong> このMessage-Idは<code>send(Mail)</code>か<code>send(Mail[])</code>メソッドが呼びだ�?た�?にのみ有効です。MimeMessageを直接送信す�?�?合には適用さ�?ません。
 453  
 	 * 
 454  
 	 * @param messageId メー�?に付けら�?�?Message-Idヘッダのドメイン部分
 455  
 	 * @throws IllegalArgumentException @を複数含んだ文字列を指定した�?�?
 456  
 	 */
 457  
 	public void setMessageId(String messageId) {
 458  1
 		if (messageId == null || messageId.length() < 1) {
 459  0
 			return;
 460  
 		}
 461  
 
 462  1
 		String[] parts = messageId.split("@");
 463  1
 		if (parts.length > 2) {
 464  0
 			throw new IllegalArgumentException("messageIdプ��叢ティに'@'を複数含むことはできません。[" + messageId
 465  0
 					+ "]");
 466  
 		}
 467  
 
 468  1
 		this.messageId = messageId;
 469  1
 	}
 470  
 
 471  
 	/**
 472  
 	 * SMTPサーバとの接続タイムアウトをセットします。
 473  
 	 * 単位はミ�?秒。デフォ�?トは5,000ミ�?秒(5秒)です。
 474  
 	 * <p>
 475  
 	 * -1を指定す�?と無限大になりますが、お薦めしません。
 476  
 	 * 
 477  
 	 * @since 1.1.4
 478  
 	 * @param connectionTimeout SMTPサーバとの接続タイムアウト
 479  
 	 */
 480  
 	public void setConnectionTimeout(int connectionTimeout) {
 481  0
 		this.connectionTimeout = connectionTimeout;
 482  0
 	}
 483  
 
 484  
 	/**
 485  
 	 * SMTPサーバへの送受信�?のタイムアウトをセットします。
 486  
 	 * 単位はミ�?秒。デフォ�?トは5,000ミ�?秒(5秒)です。
 487  
 	 * <p>
 488  
 	 * -1を指定す�?と無限大になりますが、お薦めしません。
 489  
 	 * 
 490  
 	 * @since 1.1.4
 491  
 	 * @param readTimeout SMTPサーバへの送受信�?のタイムアウト
 492  
 	 */
 493  
 	public void setReadTimeout(int readTimeout) {
 494  0
 		this.readTimeout = readTimeout;
 495  0
 	}
 496  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.