/*
 * @(#) $Id: CorrectedContentTypeDataSourceUTF7Support.java,v 1.2 2001/03/04 13:32:56 shin Exp $
 * $Revision: 1.2 $
 * Copyright (c) 2000 Shin Kinoshita All Rights Reserved.
 */
package com.sk_jp.mail;

import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.mail.Part;
import javax.mail.MessagingException;
import javax.mail.internet.ContentType;
import javax.mail.internet.ParseException;
import javax.activation.DataSource;

import com.sk_jp.io.ByteToCharUTF7;

/**
 * Content-Type:の不適合をISO-2022-JPに補正します。
 * さらにcharset=UTF-7の場合にUTF-16のストリームに変換してgetContent()を
 * 無理やり成功させます。<BR>
 * 使用方法は<PRE>
 * Object o = new DataHandler(
 *               new CorrectedContentTypeDataSource(part, charset)
 *            ).getContent();
 * </PRE><P>のようになります。</P><P>
 * スレッドセーフではありませんので利用者側で排他制御を行ってください。
 * </P>
 * @author Shin
 * @version $Revision: 1.2 $ $Date: 2001/03/04 13:32:56 $
 */
class CorrectedContentTypeDataSourceUTF7Support
            extends CorrectedContentTypeDataSource {
    private boolean utf7 = false;

    public CorrectedContentTypeDataSourceUTF7Support() {}
    public CorrectedContentTypeDataSourceUTF7Support(
                DataSource dataSource,
                String defaultCharset) {
        super(dataSource, defaultCharset);
    }
    public CorrectedContentTypeDataSourceUTF7Support(
                Part part,
                String defaultCharset)
                throws MessagingException {
        super(part, defaultCharset);
    }

    public void setDataSource(DataSource newSource) {
        super.setDataSource(newSource);
        utf7 = false;
    }
    public void setDefaultCharset(String defaultCharset) {
        super.setDefaultCharset(defaultCharset);
        utf7 = false;
    }

    public String getContentType() {
        try {
            ContentType contentType = new ContentType(super.getContentType());
            String specifiedCharset = contentType.getParameter("charset");
            if ("UTF-7".equalsIgnoreCase(specifiedCharset)) {
                // UTF-7コンバータが存在しない為、
                // 独自フィルタストリームを用いる。
                contentType.setParameter("charset", "UTF-16");
                utf7 = true;
            }
            return contentType.toString();
        } catch (ParseException e) {
            throw new InternalError();
        }
    }

    public InputStream getInputStream() throws IOException {
        if (!utf7) {
            return super.getInputStream();
        }
        InputStream in = super.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int c;

        while ((c = in.read()) != -1) {
            out.write(c);
        }

        ByteToCharUTF7 btc = new ByteToCharUTF7();
        byte[] bytes = out.toByteArray();
        char[] chars = new char[bytes.length / 2 + 1];

        btc.convert(bytes, 0, bytes.length,
                    chars, 0, chars.length);

        String string = new String(chars);
        return new ByteArrayInputStream(string.getBytes("UTF-16"));
    }
}

