2 * @(#) $Id: CorrectedContentTypeDataSourceUTF7Support.java,v 1.1.2.1 2004/09/29 00:57:59 otsuka Exp $
\r
3 * $Revision: 1.1.2.1 $
\r
4 * Copyright (c) 2000 Shin Kinoshita All Rights Reserved.
\r
6 package com.ozacc.mail.fetch.impl.sk_jp;
\r
8 import java.io.ByteArrayInputStream;
\r
9 import java.io.ByteArrayOutputStream;
\r
10 import java.io.IOException;
\r
11 import java.io.InputStream;
\r
13 import javax.activation.DataSource;
\r
14 import javax.mail.MessageAware;
\r
15 import javax.mail.MessagingException;
\r
16 import javax.mail.Part;
\r
17 import javax.mail.internet.ContentType;
\r
18 import javax.mail.internet.MimeBodyPart;
\r
19 import javax.mail.internet.MimeMessage;
\r
20 import javax.mail.internet.ParseException;
\r
22 import com.ozacc.mail.fetch.impl.sk_jp.io.ByteToCharUTF7;
\r
25 * Content-Type:の不適合をISO-2022-JPに補正します。
\r
26 * さらにcharset=UTF-7の場合にUTF-16のストリームに変換してgetContent()を
\r
28 * また、未知のTES(Content-Transfer-Encoding:)だった場合に、"7bit"
\r
31 * Object o = new DataHandler(
\r
32 * new CorrectedContentTypeDataSourceUTF7Support(part, charset)
\r
34 * </PRE><P>のようになります。</P><P>
\r
35 * スレッドセーフではありませんので利用者側で排他制御を行ってください。
\r
38 * @version $Revision: 1.1.2.1 $ $Date: 2004/09/29 00:57:59 $
\r
40 class CorrectedContentTypeDataSourceUTF7Support extends CorrectedContentTypeDataSource {
\r
42 private boolean utf7 = false;
\r
44 public CorrectedContentTypeDataSourceUTF7Support() {}
\r
46 public CorrectedContentTypeDataSourceUTF7Support(DataSource dataSource, String defaultCharset) {
\r
47 super(dataSource, defaultCharset);
\r
50 public CorrectedContentTypeDataSourceUTF7Support(Part part, String defaultCharset)
\r
51 throws MessagingException {
\r
52 super(part, defaultCharset);
\r
55 public void setDataSource(DataSource newSource) {
\r
56 super.setDataSource(newSource);
\r
60 public void setDefaultCharset(String defaultCharset) {
\r
61 super.setDefaultCharset(defaultCharset);
\r
65 public String getContentType() {
\r
67 ContentType contentType = new ContentType(super.getContentType());
\r
68 String specifiedCharset = contentType.getParameter("charset");
\r
69 if ("UTF-7".equalsIgnoreCase(specifiedCharset)) {
\r
70 // UTF-7コンバータが存在しない為、
\r
72 contentType.setParameter("charset", "UTF-16");
\r
75 return contentType.toString();
\r
76 } catch (ParseException e) {
\r
77 throw new InternalError();
\r
81 public InputStream getInputStream() throws IOException {
\r
82 InputStream in = null;
\r
83 if (isInvalidEncodingAsMultipart()) {
\r
84 // multipart/*でありながら、不正なTransfer-Encodingだった場合
\r
85 // 2001/09/01 JPhone(SH07)の送信する画像付きメイルが、
\r
86 // Content-Type: multipart/mixed
\r
87 // Content-Transfer-Encoding: base64
\r
88 // 等というメッセージを送る場合があり、JavaMailが
\r
89 // これをデコードできない問題を回避。
\r
90 // multipart/*の場合のContent-Transfer-Encodingは、
\r
91 // "7bit""8bit""binary"に限られる。
\r
92 // それ以外の場合は生ストリームを返すようにしておく。
\r
93 in = getRawInputStream();
\r
97 in = super.getInputStream();
\r
98 } catch (IOException e) {
\r
99 // ここでのIOExceptionはエンコーディング不良の可能性が高い。
\r
100 // 生InputStreamを得てリトライ
\r
101 in = getRawInputStream();
\r
109 ByteArrayOutputStream out = new ByteArrayOutputStream();
\r
112 while ((c = in.read()) != -1) {
\r
116 ByteToCharUTF7 btc = new ByteToCharUTF7();
\r
117 byte[] bytes = out.toByteArray();
\r
118 char[] chars = new char[bytes.length];
\r
120 // Bug fixed. Thanx to MOHI.
\r
121 // http://www.sk-jp.com/cgi-bin/treebbs.cgi?all=1220&s=1220
\r
122 int len = btc.convert(bytes, 0, bytes.length, chars, 0, chars.length);
\r
123 char[] w = new char[len];
\r
124 System.arraycopy(chars, 0, w, 0, len);
\r
125 String string = new String(w);
\r
126 return new ByteArrayInputStream(string.getBytes("UTF-16"));
\r
129 // Transfer-Encodingにしたがったデコードを行う前のストリームを得ます。
\r
130 // sourceがMessageAwareでない場合はnullが返されます。
\r
131 private InputStream getRawInputStream() throws IOException {
\r
132 if (!(source instanceof MessageAware)) {
\r
135 Part part = ((MessageAware)source).getMessageContext().getPart();
\r
137 if (part instanceof MimeMessage) {
\r
138 return ((MimeMessage)part).getRawInputStream();
\r
139 } else if (part instanceof MimeBodyPart) {
\r
140 return ((MimeBodyPart)part).getRawInputStream();
\r
144 } catch (MessagingException mex) {
\r
145 throw new IOException(mex.toString());
\r
149 // 不正なContent-Transfer-Encodingの場合にtrueを返します。
\r
150 private boolean isInvalidEncodingAsMultipart() {
\r
152 if (!new ContentType(getContentType()).match("multipart/*")) {
\r
155 if (!(source instanceof MessageAware)) {
\r
158 Part part = ((MessageAware)source).getMessageContext().getPart();
\r
159 String encoding = ((javax.mail.internet.MimePart)part).getEncoding();
\r
160 if ("7bit".equalsIgnoreCase(encoding) || "8bit".equalsIgnoreCase(encoding)
\r
161 || "binary".equalsIgnoreCase(encoding)) {
\r
164 } catch (Exception e) {
\r