View Javadoc

    1   package com.ozacc.mail.fetch.impl;
    2
    3   import java.io.IOException;
    4   import java.io.InputStream;
    5   import java.util.ArrayList;
    6   import java.util.Date;
    7   import java.util.Enumeration;
    8   import java.util.List;
    9
    10  import javax.mail.Address;
    11  import javax.mail.Header;
    12  import javax.mail.Message;
    13  import javax.mail.MessagingException;
    14  import javax.mail.internet.AddressException;
    15  import javax.mail.internet.InternetAddress;
    16  import javax.mail.internet.MimeMessage;
    17
    18  import org.apache.commons.logging.Log;
    19  import org.apache.commons.logging.LogFactory;
    20
    21  import com.ozacc.mail.fetch.ReceivedMail;
    22  import com.ozacc.mail.fetch.impl.sk_jp.AttachmentsExtractor;
    23  import com.ozacc.mail.fetch.impl.sk_jp.HtmlPartExtractor;
    24  import com.ozacc.mail.fetch.impl.sk_jp.MultipartUtility;
    25
    26  /***
    27   * MimeMessageからMailを生成するクラス。
    28   * <p>
    29   * 変換時に生じたチェック例外は、このクラス内でキャッチされ無視されます。
    30   * 例外が生じた項目(差出人や宛先など)に該当するMailインスタンスのプロパティには何もセットされません。
    31   *
    32   * @since 1.2
    33   * @author Tomohiro Otsuka
    34   * @version $Id: MailConverter.java,v 1.1.2.8 2005/01/18 07:21:20 otsuka Exp $
    35   */
    36  public class MailConverter {
    37
    38  	private static Log log = LogFactory.getLog(MailConverter.class);
    39
    40  	private MimeMessage[] messages;
    41
    42  	/***
    43  	 * @param mimeMessage
    44  	 */
    45  	public MailConverter(MimeMessage mimeMessage) {
    46  		this(new MimeMessage[] { mimeMessage });
    47  	}
    48
    49  	/***
    50  	 * @param mimeMessages
    51  	 */
    52  	public MailConverter(MimeMessage[] mimeMessages) {
    53  		this.messages = mimeMessages;
    54  	}
    55
    56  	/***
    57  	 * @return
    58  	 */
    59  	public ReceivedMail[] convertIntoMails() {
    60  		log.debug("計" + messages.length + "通のMimeMessageをMailに変換します。");
    61  		List list = new ArrayList();
    62  		for (int i = 0; i < messages.length; i++) {
    63  			log.debug((i + 1) + "通目のMimeMessageをMailに変換します。");
    64
    65  			MimeMessage mm = messages[i];
    66  			ReceivedMail mail = new ReceivedMail();
    67
    68  			setReturnPath(mm, mail);
    69  			setDate(mm, mail);
    70  			setFromAddress(mm, mail);
    71  			setRecipientAddresses(mm, mail);
    72  			setMessageId(mm, mail);
    73  			setReplyToAddress(mm, mail);
    74  			setSubject(mm, mail);
    75  			setXHeaders(mm, mail);
    76  			setText(mm, mail);
    77  			setHtmlText(mm, mail);
    78  			setAttachmentFiles(mm, mail);
    79
    80  			setSize(mm, mail);
    81
    82  			mail.setMessage(mm);
    83
    84  			log.debug((i + 1) + "通目のMimeMessageをMailに変換しました。");
    85  			log.debug(mail.toString());
    86
    87  			list.add(mail);
    88  		}
    89  		log.debug("計" + messages.length + "通のMimeMessageをMailに変換しました。");
    90  		return (ReceivedMail[])list.toArray(new ReceivedMail[list.size()]);
    91  	}
    92
    93  	/***
    94  	 * 指定されたMimeMessageに添付されているファイルを全て抽出し、
    95  	 * 指定されたReceivedMailにセットします。
    96  	 *
    97  	 * @param mm
    98  	 * @param mail
    99  	 */
    100 	private void setAttachmentFiles(MimeMessage mm, ReceivedMail mail) {
    101 		try {
    102 			AttachmentsExtractor ae = new AttachmentsExtractor(
    103 					AttachmentsExtractor.MODE_IGNORE_MESSAGE
    104 							| AttachmentsExtractor.MODE_IGNORE_INLINE);
    105 			MultipartUtility.process(mm, ae);
    106 			for (int i = 0, num = ae.getCount(); i < num; i++) {
    107 				String fileName = ae.getFileName(i);
    108 				InputStream is = ae.getInputStream(i);
    109 				mail.addFile(is, fileName);
    110 			}
    111 		} catch (IOException e) {
    112 			log.error("添付ファイルの取得に失敗しました。", e);
    113 		} catch (MessagingException e) {
    114 			// ignore
    115 			log.warn(e.getMessage());
    116 		}
    117 	}
    118
    119 	private void setXHeaders(MimeMessage mm, ReceivedMail mail) {
    120 		log.debug("X-HeaderをMailにセットします。");
    121 		String[] xHeaders = null;
    122 		Enumeration headerEnum = null;
    123 		try {
    124 			headerEnum = mm.getAllHeaders();
    125 		} catch (MessagingException e) {
    126 			// ignore
    127 			log.warn(e.getMessage());
    128 		}
    129 		while (headerEnum != null && headerEnum.hasMoreElements()) {
    130 			Header header = (Header)headerEnum.nextElement();
    131 			if (header.getName().startsWith("X-")) {
    132 				mail.addXHeader(header.getName(), header.getValue());
    133 			}
    134 		}
    135 	}
    136
    137 	private void setReplyToAddress(MimeMessage mm, ReceivedMail mail) {
    138 		log.debug("Reply-ToアドレスをMailにセットします。");
    139 		Address[] addresses = null;
    140 		try {
    141 			addresses = mm.getReplyTo();
    142 		} catch (MessagingException e) {
    143 			// ignore
    144 			log.warn(e.getMessage());
    145 		}
    146 		if (addresses != null) {
    147 			log.debug(addresses.length + "つのReply-Toアドレスが見つかりました。最初のアドレスのみ取得されます。");
    148 			for (int j = 0; j < addresses.length; j++) {
    149 				Address address = addresses[j];
    150 				mail.setReplyTo((InternetAddress)address);
    151 				break;
    152 			}
    153 		} else {
    154 			log.debug("Reply-Toアドレスは見つかりませんでした。");
    155 		}
    156 	}
    157
    158 	/***
    159 	 * メールの容量(byte)をMimeMessageから取得してReceivedMailにセットします。
    160 	 * 取得に失敗した場合は -1 をセットします。
    161 	 *
    162 	 * @param mm
    163 	 * @param mail
    164 	 */
    165 	private void setSize(MimeMessage mm, ReceivedMail mail) {
    166 		try {
    167 			mail.setSize(mm.getSize());
    168 		} catch (MessagingException e) {
    169 			mail.setSize(-1);
    170 		}
    171 	}
    172
    173 	/***
    174 	 * @param mm
    175 	 * @param mail
    176 	 * @throws MessagingException
    177 	 */
    178 	private void setHtmlText(MimeMessage mm, ReceivedMail mail) {
    179 		try {
    180 			HtmlPartExtractor hpe = new HtmlPartExtractor();
    181 			MultipartUtility.process(mm, hpe);
    182 			String htmlText = hpe.getHtml();
    183 			mail.setHtmlText(htmlText);
    184 		} catch (MessagingException e) {
    185 			// ignore
    186 			log.warn(e.getMessage());
    187 		}
    188 	}
    189
    190 	private void setText(MimeMessage mm, ReceivedMail mail) {
    191 		try {
    192 			String text = MultipartUtility.getPlainText(mm);
    193 			mail.setText(text);
    194 		} catch (MessagingException e) {
    195 			// ignore
    196 			log.warn(e.getMessage());
    197 		}
    198 	}
    199
    200 	private void setMessageId(MimeMessage mm, ReceivedMail mail) {
    201 		try {
    202 			String messageId = mm.getMessageID();
    203 			mail.setMessageId(messageId);
    204 		} catch (MessagingException e) {
    205 			// ignore
    206 			log.warn(e.getMessage());
    207 		}
    208 	}
    209
    210 	private void setSubject(MimeMessage mm, ReceivedMail mail) {
    211 		try {
    212 			String subject = mm.getSubject();
    213 			mail.setSubject(subject);
    214 		} catch (MessagingException e) {
    215 			// ignore
    216 			log.warn(e.getMessage());
    217 		}
    218 	}
    219
    220 	private void setDate(MimeMessage mm, ReceivedMail mail) {
    221 		try {
    222 			Date d = mm.getSentDate();
    223 			mail.setDate(d);
    224 		} catch (MessagingException e) {
    225 			// ignore
    226 			log.warn(e.getMessage());
    227 		}
    228 	}
    229
    230 	/***
    231 	 * Return-Pathアドレスは必ずしもセットされてはいません。
    232 	 * 特にspam系のメールでは不正なフォーマットのメールアドレスが
    233 	 * セットされている場合もあるので要注意。
    234 	 *
    235 	 * @param mm
    236 	 * @param mail
    237 	 */
    238 	private void setReturnPath(MimeMessage mm, ReceivedMail mail) {
    239 		log.debug("Return-Pathアドレスを検出します。");
    240 		String[] returnPath = null;
    241 		try {
    242 			returnPath = mm.getHeader("Return-Path");
    243 		} catch (MessagingException e) {
    244 			// ignore
    245 			log.warn(e.getMessage());
    246 		}
    247 		if (returnPath != null && returnPath.length > 0) {
    248 			String email = returnPath[0].substring(1, returnPath[0].length() - 1);
    249 			if (email.length() > 0) {
    250 				try {
    251 					mail.setReturnPath(email);
    252 					log.debug("Return-PathアドレスをMailにセットしました。[Return-Path='" + email + "']");
    253 				} catch (IllegalArgumentException e) {
    254 					log.warn("Return-Pathアドレスが不正なメールアドレスフォーマットです。[Return-Path='" + email + "']");
    255 				}
    256 			} else {
    257 				log.debug("Return-Pathアドレスは見つかりませんでした。");
    258 			}
    259 		} else {
    260 			log.debug("Return-Pathアドレスは見つかりませんでした。");
    261 		}
    262 	}
    263
    264 	private void setFromAddress(MimeMessage mm, ReceivedMail mail) {
    265 		log.debug("Fromアドレスを検出します。");
    266 		Address[] addresses = null;
    267 		try {
    268 			addresses = mm.getFrom();
    269 		} catch (MessagingException e) {
    270 			// ignore
    271 			log.warn(e.getMessage());
    272 		}
    273 		if (addresses != null) {
    274 			log.debug(addresses.length + "つのFromアドレスが見つかりました。");
    275 			for (int j = 0; j < addresses.length; j++) {
    276 				InternetAddress address = (InternetAddress)addresses[j];
    277 				mail.setFrom(address);
    278 				log.debug("FromアドレスをMailにセットしました。[From='" + address.toUnicodeString() + "']");
    279 			}
    280 		} else {
    281 			log.debug("Fromアドレスは見つかりませんでした。");
    282 		}
    283 	}
    284
    285 	private void setRecipientAddresses(MimeMessage mm, ReceivedMail mail) {
    286 		/*
    287 		 * TOアドレスのパース
    288 		 */
    289 		log.debug("Toアドレスを検出します。");
    290 		Address[] toAddresses = null;
    291 		try {
    292 			toAddresses = mm.getRecipients(Message.RecipientType.TO);
    293 		} catch (AddressException e) {
    294 			log.warn("不正なメールアドレスが検出されました。[" + e.getRef() + "]");
    295 		} catch (MessagingException e) {
    296 			// ignore
    297 			log.warn(e.getMessage());
    298 		}
    299 		if (toAddresses != null) {
    300 			log.debug(toAddresses.length + "つのToアドレスが見つかりました。");
    301 			for (int j = 0; j < toAddresses.length; j++) {
    302 				InternetAddress address = (InternetAddress)toAddresses[j];
    303 				mail.addTo(address);
    304 				log.debug("ToアドレスをMailにセットしました。[To='" + address.toUnicodeString() + "']");
    305 			}
    306 		} else {
    307 			log.debug("Toアドレスは見つかりませんでした。");
    308 		}
    309
    310 		/*
    311 		 * CCアドレスのパース
    312 		 */
    313 		log.debug("Ccアドレスを検出します。");
    314 		Address[] ccAddresses = null;
    315 		try {
    316 			ccAddresses = mm.getRecipients(Message.RecipientType.CC);
    317 		} catch (AddressException e) {
    318 			log.warn("不正なメールアドレスが検出されました。[" + e.getRef() + "]");
    319 		} catch (MessagingException e) {
    320 			// ignore
    321 			log.warn(e.getMessage());
    322 		}
    323 		if (ccAddresses != null) {
    324 			log.debug(ccAddresses.length + "つのCcアドレスが見つかりました。");
    325 			for (int j = 0; j < ccAddresses.length; j++) {
    326 				InternetAddress address = (InternetAddress)ccAddresses[j];
    327 				mail.addCc(address);
    328 				log.debug("CcアドレスをMailにセットしました。[Cc='" + address.toUnicodeString() + "']");
    329 			}
    330 		} else {
    331 			log.debug("Ccアドレスは見つかりませんでした。");
    332 		}
    333 	}
    334
    335 }