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

import java.util.Properties;

import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.FolderNotFoundException;
import javax.mail.internet.MimeMessage;

/**
 * 接続情報を毎回指定するシンプルなメイル受信クラスです。
 * @author Shin
 * @version $Revision: 1.2 $ $Date: 2001/03/04 13:32:57 $
 */
public class SimpleRetriever {
    private Store store;
    private Folder currentFolder = null;

    /**
     * メイル受信オブジェクトを生成します。
     * @param protocol 接続プロトコル名
     */
    public SimpleRetriever(String protocol) throws NoSuchProviderException {
        Session session = Session.getInstance(new Properties(), null);
        // "mail.debug"のみシステムプロパティの情報を利用する事にします。
        session.setDebug(Boolean.getBoolean("mail.debug"));
        store = session.getStore(protocol);
    }

    /**
     * サーバに接続します。
     * @param host 接続先ホスト
     * @param user ユーザ名
     * @param password パスワード
     * @exception MessagingException 接続に失敗
     */
    public void connect(String host,
                        String user,
                        String password) throws MessagingException {
        connect(host, -1, user, password);
    }

    /**
     * サーバに接続します。
     * @param host 接続先ホスト
     * @param port ポート番号
     * @param user ユーザ名
     * @param password パスワード
     * @exception MessagingException 接続に失敗
     */
    public synchronized void connect(String host,
                                     int port,
                                     String user,
                                     String password)
                 throws MessagingException {
        store.connect(host, port, user, password);
    }

    /**
     * サーバから切断します。
     * <P>
     * メッセージに対する処理が終わってから呼び出す必要があります。<BR>
     * 呼び出さずに放置した場合、サーバのタイムアウトで切断されます。<BR>
     * 削除マークを付加したメッセージはサーバから削除されます。
     * </P>
     */
    public synchronized void disconnect() {
        if (currentFolder != null && currentFolder.isOpen()) {
            try {
                currentFolder.close(true);
            } catch (MessagingException e) {
                e.printStackTrace();
            }
            currentFolder = null;
        }
        try {
            store.close();
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 書き込み属性でフォルダをオープンしたい場合にtrueにセットします。
     * <P>
     * 現在オープン中のフォルダの属性は変更されません。<BR>
     * 次回setCurrentFolder()を呼び出したときから有効になります。
     * </P>
     * @param writable フォルダオープン時の属性としてREAD_WRITEを用いるか
     */
    private boolean writable = false;
    public synchronized void setWritable(boolean writable) {
        this.writable = writable;
    }

    /**
     * メッセージを取り出す対象フォルダを設定します。
     * <P>
     * ルートフォルダから見たフォルダへのパスを指定します。<BR>
     * 呼び出しと同時にフォルダのオープンを行います。<BR>
     * 呼び出し前に設定されていたフォルダはクローズされます。
     * </P>
     * @param name フォルダの名称
     * @exception FolderNotFoundException フォルダが見つからない
     * @exception MessagingException フォルダのオープンに失敗した場合など
     */
    public synchronized void setCurrentFolder(String name)
                throws MessagingException {
        if (currentFolder != null && currentFolder.isOpen()) {
            currentFolder.close(true);
        }
        currentFolder = store.getFolder(name);
        if (currentFolder == null) {
            throw new FolderNotFoundException();
        }
        if (writable) {
            currentFolder.open(Folder.READ_WRITE);
        } else {
            currentFolder.open(Folder.READ_ONLY);
        }
    }

    /**
     * 現在のフォルダ上の全メッセージを取得します。
     * <P>
     * 返されるメッセージオブジェクトの内容は
     * まだダウンロードされていない可能性があります。
     * </P>
     * @return 現在のフォルダ上の全メッセージオブジェクト
     * @exception MessagingException
     */
    public synchronized MimeMessage[] get() throws MessagingException {
        if (currentFolder == null) {
            setCurrentFolder("INBOX");
        }

        Message[] messages = currentFolder.getMessages();
        MimeMessage[] mimeMessages = new MimeMessage[messages.length];

        for (int i = 0; i < messages.length; i++) {
            mimeMessages[i] = (MimeMessage)messages[i];
        }
        return mimeMessages;
    }

    /**
     * 現在のフォルダ上の指定メッセージを取得します。
     * <P>
     * 返されるメッセージオブジェクトの内容は
     * まだダウンロードされていない可能性があります。
     * </P>
     * @param num
     * @return 現在のフォルダ上の指定メッセージ番号のメッセージオブジェクト
     * @exception MessagingException
     */
    public synchronized MimeMessage get(int num) throws MessagingException {
        if (currentFolder == null) {
            setCurrentFolder("INBOX");
        }

        try {
            return (MimeMessage)currentFolder.getMessage(num);
        } catch (IndexOutOfBoundsException e) {
            throw new MessagingException("Message number out of bounds", e);
        }
    }

    protected void finalize() throws Throwable {
        disconnect();
    }

    public static void main(String[] args) throws Exception {
        String protocol = args[0];
        String host = args[1];
        String user = args[2];
        String pass = args[3];

        SimpleRetriever r = new SimpleRetriever(protocol);
        r.connect(host, user, pass);

        Message[] m = r.get();
        System.out.println("******************* Recieved: " + m.length);
        for (int i = 0; i < m.length; i++) {
            m[i].writeTo(System.out);
            System.out.println("*******************");
        }
        r.disconnect();
    }
/*
    public static void main(String[] args) throws Exception {
        String protocol = args[0];
        String host = args[1];
        String user = args[2];
        String pass = args[3];
        int num = 0;
        if (args.length > 4) {
            num = Integer.parseInt(args[4]);
        }


        SimpleRetriever r = new SimpleRetriever(protocol);
        r.connect(host, user, pass);

        if (num > 0) {
            MimeMessage m = r.get(num);
            m.writeTo(System.out);

            r.disconnect();
            r.connect(host, user, pass);
            m = r.get(num);
            m.writeTo(System.out);
        } else {
            MimeMessage[] m = r.get();
            System.out.println("******************* Recieved: " + m.length);
            for (int i = 0; i < m.length; i++) {
                m[i].writeTo(System.out);
                System.out.println("*******************");
                MultipartUtility.dump(m[i]);
            }
        }
        r.disconnect();
    }
*/
}

