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 }