View Javadoc

    1   /*
    2    * @(#) $Id: MultipartUtility.java,v 1.1.2.2 2004/10/24 10:26:50 otsuka Exp $
    3    * $Revision: 1.1.2.2 $
    4    * Copyright (c) 2000 Shin Kinoshita All Rights Reserved.
    5    */
    6   package com.ozacc.mail.fetch.impl.sk_jp;
    7
    8   import java.io.IOException;
    9   import java.io.UnsupportedEncodingException;
    10
    11  import javax.activation.DataHandler;
    12  import javax.mail.MessagingException;
    13  import javax.mail.Multipart;
    14  import javax.mail.Part;
    15  import javax.mail.internet.ContentType;
    16  import javax.mail.internet.MimeBodyPart;
    17  import javax.mail.internet.MimeMultipart;
    18
    19  /***
    20   * メッセージボディを取り出す手段を提供するstaticメソッドのセットです。
    21   * <p>
    22   * </p>
    23   * @version $Revision: 1.1.2.2 $ $Date: 2004/10/24 10:26:50 $
    24   * @author Shin
    25   * @author Tomohiro Otsuka
    26   */
    27  public class MultipartUtility {
    28
    29  	private static final String JIS_CHARSET = "ISO-2022-JP";
    30
    31  	/***
    32  	 * 指定パートのボディを返します。
    33  	 * <P>
    34  	 * Part#getContent()の代わりです。
    35  	 * MIMEに準拠しないContent-Type:の補正を行います。
    36  	 * charset指定がない場合は"ISO-2022-JP"を補います。
    37  	 * </P><P>
    38  	 * パートがUTF-7の場合も正常に内容を取得出来ます。
    39  	 * </P>
    40  	 */
    41  	public static Object getContent(Part part) throws MessagingException, IOException {
    42  		return getContent(part, JIS_CHARSET);
    43  	}
    44
    45  	private static CorrectedContentTypeDataSource correctedDataSource = new CorrectedContentTypeDataSourceUTF7Support();
    46
    47  	private static DataHandler correctedDataHandler = new DataHandler(correctedDataSource);
    48
    49  	/***
    50  	 * 指定パートのボディを返します。
    51  	 * <P>
    52  	 * MIMEに準拠しないContent-Type:の補正を行います。
    53  	 * charset指定がない場合はcharsetで指定されたもので補います。
    54  	 * </P><P>
    55  	 * パートがUTF-7の場合も正常に内容を取得出来ます。
    56  	 * </P>
    57  	 */
    58  	public static Object getContent(Part part, String charset) throws MessagingException,
    59  																IOException {
    60  		synchronized (correctedDataSource) {
    61
    62  			correctedDataSource.setPart(part);
    63  			try {
    64  				correctedDataSource.setDefaultCharset(charset);
    65  				return correctedDataHandler.getContent();
    66  			} catch (UnsupportedEncodingException e) {
    67  				/*
    68  				 * 不正な文字コードがcharsetにセットされ例外がスローされた場合に
    69  				 * JIS_CHARSETに文字コードを置き換え、再度ホディの取得を試みます。
    70  				 *
    71  				 * by otsuka
    72  				 */
    73  				correctedDataSource.setForceCharset(JIS_CHARSET);
    74  				return correctedDataHandler.getContent();
    75  			}
    76
    77  		}
    78  	}
    79
    80  	/***
    81  	 * 指定パート配下で最初に見つけたテキストパートのボディを返します。
    82  	 * process()を呼び出して結果を返すだけのconvenience methodです。
    83  	 */
    84  	public static String getFirstPlainText(Part part) throws MessagingException {
    85  		FirstPlainPartExtractor h = new FirstPlainPartExtractor();
    86  		process(part, h);
    87  		return h.getText();
    88  	}
    89
    90  	/***
    91  	 * 指定パート配下のinlineなテキストパートを集めて表示用のボディを返します。
    92  	 * process()を呼び出して結果を返すだけのconvenience methodです。
    93  	 */
    94  	public static String getPlainText(Part part) throws MessagingException {
    95  		PlainPartExtractor h = new PlainPartExtractor();
    96  		process(part, h);
    97  		return h.getText();
    98  	}
    99
    100 	/***
    101 	 * 指定パート配下の各パートを処理します。
    102 	 * <P>
    103 	 * すべてのPartに対してPartHandlerが呼び出されます。<BR>
    104 	 * </P>
    105 	 */
    106 	public static void process(Part part, PartHandler handler) throws MessagingException {
    107 		process(part, handler, null);
    108 	}
    109
    110 	private static boolean process(Part part, PartHandler handler, ContentType context)
    111 																						throws MessagingException {
    112 		try {
    113 			if (part.isMimeType("multipart/*")) {
    114 				Multipart mp = (Multipart)part.getContent();
    115 				ContentType cType = new ContentType(part.getContentType());
    116 				for (int i = 0; i < mp.getCount(); i++) {
    117 					if (!process(mp.getBodyPart(i), handler, cType)) {
    118 						return false;
    119 					}
    120 				}
    121 				return true;
    122 			}
    123 			return handler.processPart(part, context);
    124 		} catch (IOException e) {
    125 			throw new MessagingException("Got exception \nin " + part + "\n", e);
    126 		}
    127 	}
    128
    129 	/***
    130 	 * 指定partにbodyPartを追加します。
    131 	 * partがマルチパーとコンテナの場合はそのコンテナにbodyPartを追加します。
    132 	 * そうでない場合はpartのボディとしてmultipart/mixedのコンテナを設定し、
    133 	 * 元のpartのボディとbodyPartのボディをそのコンテナに追加します。
    134 	 */
    135 	public static void addBodyPart(Part part, MimeBodyPart bodyPart) throws MessagingException,
    136 																	IOException {
    137 		if (part.isMimeType("multipart/*")) {
    138 			((MimeMultipart)part.getContent()).addBodyPart(bodyPart);
    139 			return;
    140 		}
    141 		// 仮
    142 		MimeMultipart mp = new MimeMultipart("mixed");
    143 		MimeBodyPart original = new MimeBodyPart();
    144 		original.setContent(part.getContent(), part.getContentType());
    145 		mp.addBodyPart(original);
    146 		mp.addBodyPart(bodyPart);
    147 		part.setContent(mp);
    148 	}
    149
    150 	/***
    151 	 * partのツリー構造をダンプするデバッグ用メソッドです。
    152 	 */
    153 	public static void dump(Part part) {
    154 		dump(part, 0);
    155 	}
    156
    157 	private static void dump(Part part, int layer) {
    158 		for (int i = 0; i < layer; i++) {
    159 			System.out.print("    ");
    160 		}
    161 		try {
    162 			System.out.println(part.getClass() + ":" + part.getContentType());
    163 			if (part.isMimeType("multipart/*")) {
    164 				MimeMultipart mp = (MimeMultipart)part.getContent();
    165 				for (int i = 0; i < mp.getCount(); i++) {
    166 					dump(mp.getBodyPart(i), layer + 1);
    167 				}
    168 			}
    169 		} catch (Exception e) {
    170 			e.printStackTrace();
    171 		}
    172 	}
    173 }