// [ByteArraydataSource.java]
// demoのByteArrayDataSourceを改良して日本語文字列に対応したものです。
package com.sk_jp.mail;

import java.io.*;
import javax.mail.internet.ContentType;
import javax.mail.internet.ParseException;
import javax.activation.DataSource;

/**
 * 任意のバイナリデータ及びテキストデータを表現するDataSourceです。
 * charsetパラメタに対応しています。
 */
public class ByteArrayDataSource implements DataSource {
    private byte[] data;
    private String contentType;

    /**
     * バイナリデータのデータソースを生成します。
     */
    public ByteArrayDataSource(byte[] data, String contentType) {
        this.data = data;
        this.contentType = contentType;
    }

    /**
     * バイナリデータのデータソースを生成します。
     */
    public ByteArrayDataSource(InputStream in, String contentType)
                throws IOException {
        this.contentType = contentType;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buf = new byte[2048];
        int len;

        while ((len = in.read(buf)) != -1) {
            out.write(buf, 0, len);
        }
        data = out.toByteArray();
    }

    /**
     * 文字ストリームからtext/*用のデータソースを生成します。
     * contentTypeのcharsetパラメタに応じてエンコードされたデータを生成します。
     * charsetパラメタは、Readerに施されたエンコーディングと
     * 同じものが指定されなければなりません。
     */
    public ByteArrayDataSource(Reader in, String contentType)
                throws IOException {
        this.contentType = contentType;
        String charset = null;
        try {
            ContentType ct = new ContentType(contentType);
            charset = ct.getParameter("charset");
        } catch (ParseException e) {}
        if (charset == null) {
            charset = "us-ascii";
        }
        BufferedReader reader = new BufferedReader(in);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        String line;

        while ((line = reader.readLine()) != null) {
            out.write(line.getBytes(charset));
            out.write('\r');
            out.write('\n');
        }
        data = out.toByteArray();
    }

    /**
     * 文字列からtext/*用のデータソースを生成します。
     * contentTypeのcharsetパラメタに応じてエンコードされたデータを生成します。
     */
    public ByteArrayDataSource(String text, String contentType) {
        this.contentType = contentType;
        String charset = null;
        try {
            ContentType ct = new ContentType(contentType);
            charset = ct.getParameter("charset");
        } catch (ParseException e) {}
        if (charset == null) {
            charset = "us-ascii";
        }
        try {
            data = text.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            try {
                data = text.getBytes("us-ascii");
            } catch (UnsupportedEncodingException e2) {}
        }
    }

    //////////////////////////////////////////////////////////////////////////
    // 以降はDataSource interfaceのメソッド群です。
    // 重要なのはgetInputStream()でそのデータのストリーム表現を返すことです。

    /**
     * Return an InputStream for the data.
     * Note - a new stream must be returned each time.
     */
    public InputStream getInputStream() throws IOException {
        if (data == null) {
            throw new IOException("no data");
        }
        return new ByteArrayInputStream(data);
    }
    public OutputStream getOutputStream() throws IOException {
        throw new IOException("cannot do this");
    }

    public String getContentType() {
        return contentType;
    }

    public String getName() {
        return "dummy";
    }
}

