| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| com.ozacc.mail.fetch.impl.sk_jp.CorrectedContentTypeDataSourceUTF7Support |
|
|
| 1 | /* |
|
| 2 | * @(#) $Id: CorrectedContentTypeDataSourceUTF7Support.java,v 1.1.2.1 2004/09/29 00:57:59 otsuka Exp $ |
|
| 3 | * $Revision: 1.1.2.1 $ |
|
| 4 | * Copyright (c) 2000 Shin Kinoshita All Rights Reserved. |
|
| 5 | */ |
|
| 6 | package com.ozacc.mail.fetch.impl.sk_jp; |
|
| 7 | ||
| 8 | import java.io.ByteArrayInputStream; |
|
| 9 | import java.io.ByteArrayOutputStream; |
|
| 10 | import java.io.IOException; |
|
| 11 | import java.io.InputStream; |
|
| 12 | ||
| 13 | import javax.activation.DataSource; |
|
| 14 | import javax.mail.MessageAware; |
|
| 15 | import javax.mail.MessagingException; |
|
| 16 | import javax.mail.Part; |
|
| 17 | import javax.mail.internet.ContentType; |
|
| 18 | import javax.mail.internet.MimeBodyPart; |
|
| 19 | import javax.mail.internet.MimeMessage; |
|
| 20 | import javax.mail.internet.ParseException; |
|
| 21 | ||
| 22 | import com.ozacc.mail.fetch.impl.sk_jp.io.ByteToCharUTF7; |
|
| 23 | ||
| 24 | /** |
|
| 25 | * Content-Type:の不適合をISO-2022-JPに補正します。 |
|
| 26 | * さらにcharset=UTF-7の�?合にUTF-16のストリームに変換してgetContent()�? |
|
| 27 | * 無�?や�?成功させます。<BR> |
|
| 28 | * また、未知のTES(Content-Transfer-Encoding:)だった�?合に、"7bit" |
|
| 29 | * と見なしてボディを取得します。 |
|
| 30 | * 使用�?法は<PRE> |
|
| 31 | * Object o = new DataHandler( |
|
| 32 | * new CorrectedContentTypeDataSourceUTF7Support(part, charset) |
|
| 33 | * ).getContent(); |
|
| 34 | * </PRE><P>のようになります。</P><P> |
|
| 35 | * ス�?ッドセーフではありませんので利用者側で排他制御を行ってください。 |
|
| 36 | * </P> |
|
| 37 | * @author Shin |
|
| 38 | * @version $Revision: 1.1.2.1 $ $Date: 2004/09/29 00:57:59 $ |
|
| 39 | */ |
|
| 40 | class CorrectedContentTypeDataSourceUTF7Support extends CorrectedContentTypeDataSource { |
|
| 41 | ||
| 42 | 0 | private boolean utf7 = false; |
| 43 | ||
| 44 | 0 | public CorrectedContentTypeDataSourceUTF7Support() {} |
| 45 | ||
| 46 | public CorrectedContentTypeDataSourceUTF7Support(DataSource dataSource, String defaultCharset) { |
|
| 47 | 0 | super(dataSource, defaultCharset); |
| 48 | 0 | } |
| 49 | ||
| 50 | public CorrectedContentTypeDataSourceUTF7Support(Part part, String defaultCharset) |
|
| 51 | throws MessagingException { |
|
| 52 | 0 | super(part, defaultCharset); |
| 53 | 0 | } |
| 54 | ||
| 55 | public void setDataSource(DataSource newSource) { |
|
| 56 | 0 | super.setDataSource(newSource); |
| 57 | 0 | utf7 = false; |
| 58 | 0 | } |
| 59 | ||
| 60 | public void setDefaultCharset(String defaultCharset) { |
|
| 61 | 0 | super.setDefaultCharset(defaultCharset); |
| 62 | 0 | utf7 = false; |
| 63 | 0 | } |
| 64 | ||
| 65 | public String getContentType() { |
|
| 66 | try { |
|
| 67 | 0 | ContentType contentType = new ContentType(super.getContentType()); |
| 68 | 0 | String specifiedCharset = contentType.getParameter("charset"); |
| 69 | 0 | if ("UTF-7".equalsIgnoreCase(specifiedCharset)) { |
| 70 | // UTF-7コンバータが存在しない為、 |
|
| 71 | // 独自フィ�?タストリームを用い�?。 |
|
| 72 | 0 | contentType.setParameter("charset", "UTF-16"); |
| 73 | 0 | utf7 = true; |
| 74 | } |
|
| 75 | 0 | return contentType.toString(); |
| 76 | 0 | } catch (ParseException e) { |
| 77 | 0 | throw new InternalError(); |
| 78 | } |
|
| 79 | } |
|
| 80 | ||
| 81 | public InputStream getInputStream() throws IOException { |
|
| 82 | 0 | InputStream in = null; |
| 83 | 0 | if (isInvalidEncodingAsMultipart()) { |
| 84 | // multipart/*でありながら、不正なTransfer-Encodingだった�?�? |
|
| 85 | // 2001/09/01 JPhone(SH07)の送信す�?画�?付きメイ�?が、 |
|
| 86 | // Content-Type: multipart/mixed |
|
| 87 | // Content-Transfer-Encoding: base64 |
|
| 88 | // 等というメッセージを送�?�?合があり、JavaMailが |
|
| 89 | // こ�?をデコードできない問題を回避。 |
|
| 90 | // multipart/*の�?合のContent-Transfer-Encodingは、 |
|
| 91 | // "7bit""8bit""binary"に限ら�?�?。 |
|
| 92 | // そ�?以外の�?合は生ストリームを返すようにしておく。 |
|
| 93 | 0 | in = getRawInputStream(); |
| 94 | } |
|
| 95 | 0 | if (in == null) { |
| 96 | try { |
|
| 97 | 0 | in = super.getInputStream(); |
| 98 | 0 | } catch (IOException e) { |
| 99 | // ここでのIOExceptionはエンコーディング不良の可能性が高い。 |
|
| 100 | // 生InputStreamを得て�?トライ |
|
| 101 | 0 | in = getRawInputStream(); |
| 102 | 0 | if (in == null) |
| 103 | 0 | throw e; |
| 104 | } |
|
| 105 | } |
|
| 106 | 0 | if (!utf7) { |
| 107 | 0 | return in; |
| 108 | } |
|
| 109 | 0 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| 110 | int c; |
|
| 111 | ||
| 112 | 0 | while ((c = in.read()) != -1) { |
| 113 | 0 | out.write(c); |
| 114 | } |
|
| 115 | ||
| 116 | 0 | ByteToCharUTF7 btc = new ByteToCharUTF7(); |
| 117 | 0 | byte[] bytes = out.toByteArray(); |
| 118 | 0 | char[] chars = new char[bytes.length]; |
| 119 | ||
| 120 | // Bug fixed. Thanx to MOHI. |
|
| 121 | // http://www.sk-jp.com/cgi-bin/treebbs.cgi?all=1220&s=1220 |
|
| 122 | 0 | int len = btc.convert(bytes, 0, bytes.length, chars, 0, chars.length); |
| 123 | 0 | char[] w = new char[len]; |
| 124 | 0 | System.arraycopy(chars, 0, w, 0, len); |
| 125 | 0 | String string = new String(w); |
| 126 | 0 | return new ByteArrayInputStream(string.getBytes("UTF-16")); |
| 127 | } |
|
| 128 | ||
| 129 | // Transfer-Encodingにしたがったデコードを行う前のストリームを得ます。 |
|
| 130 | // sourceがMessageAwareでない�?合はnullが返さ�?ます。 |
|
| 131 | private InputStream getRawInputStream() throws IOException { |
|
| 132 | 0 | if (!(source instanceof MessageAware)) { |
| 133 | 0 | return null; |
| 134 | } |
|
| 135 | 0 | Part part = ((MessageAware)source).getMessageContext().getPart(); |
| 136 | try { |
|
| 137 | 0 | if (part instanceof MimeMessage) { |
| 138 | 0 | return ((MimeMessage)part).getRawInputStream(); |
| 139 | 0 | } else if (part instanceof MimeBodyPart) { |
| 140 | 0 | return ((MimeBodyPart)part).getRawInputStream(); |
| 141 | } else { |
|
| 142 | 0 | return null; |
| 143 | } |
|
| 144 | 0 | } catch (MessagingException mex) { |
| 145 | 0 | throw new IOException(mex.toString()); |
| 146 | } |
|
| 147 | } |
|
| 148 | ||
| 149 | // 不正なContent-Transfer-Encodingの�?合にtrueを返します。 |
|
| 150 | private boolean isInvalidEncodingAsMultipart() { |
|
| 151 | try { |
|
| 152 | 0 | if (!new ContentType(getContentType()).match("multipart/*")) { |
| 153 | 0 | return false; |
| 154 | } |
|
| 155 | 0 | if (!(source instanceof MessageAware)) { |
| 156 | 0 | return false; |
| 157 | } |
|
| 158 | 0 | Part part = ((MessageAware)source).getMessageContext().getPart(); |
| 159 | 0 | String encoding = ((javax.mail.internet.MimePart)part).getEncoding(); |
| 160 | 0 | if ("7bit".equalsIgnoreCase(encoding) || "8bit".equalsIgnoreCase(encoding) |
| 161 | 0 | || "binary".equalsIgnoreCase(encoding)) { |
| 162 | 0 | return false; |
| 163 | } |
|
| 164 | 0 | } catch (Exception e) { |
| 165 | // この�?合も不正だ、と。 |
|
| 166 | } |
|
| 167 | 0 | return true; |
| 168 | } |
|
| 169 | ||
| 170 | } |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |