/*
 * HFileWriter.java
 * 
 * Author: http://www.hrtdotnet.jp/
 * 
 */
package jp.hrtdotnet.java.io;

import java.io.*;

/**
 * ファイル出力（書込み）を行うクラスです。
 * ファイルを作成する際に同名のファイルが存在する場合はシーケンス番号を付け、
 * 既存のファイルが上書きされるのを防ぎます。
 * シーケンス番号が付与された際のファイル名のパターンは
 * {@link HFile#getOtherFileName(String, int) HFile#getOtherFileName(String, int)},
 * {@link HFile#getOtherFileName(String) HFile#getOtherFileName(String)}に依存します。
 * 
 * @version 2.0
 * @author hrtdotnet.jp
 * <br>http://www.hrtdotnet.jp/
 * @since 2.0
 */
public class HFileWriter extends HWriter {
    
    //保存ファイル
    private HFile hFile = null;
    //ディレクトリ自動生成フラグ
    private boolean directoryFlg = false;
    //シーケンス番号の付加文字列
    private String alias = null;
    //シーケンス番号の桁数
    private int digit = 0;
//    //入力ストリーム
//    private InputStream inputStream = null;

    /**
     * ファイル出力（書込み）オブジェクトを生成します。
     * シーケンス番号の付加は有効ですが、桁数指定はされません。
     * 
     * @param filePath 作成ファイルパス
     * @param directoryFlg ディレクトリを自動生成する場合はtrue、そうでなければfalse
     * @param alias エイリアス
     * @throws IOException filePathが不正な場合
     * @since 2.0
     */
    public HFileWriter(String filePath, boolean directoryFlg, String alias) throws IOException {
        this(new HFile(filePath), directoryFlg, alias);
    }
    
    /**
     * ファイル出力（書込み）オブジェクトを生成します。
     * シーケンス番号の付加は有効ですが、桁数指定はされません。
     * 
     * @param hFile 作成ファイルのHFileオブジェクト
     * @param directoryFlg ディレクトリを自動生成する場合はtrue、そうでなければfalse
     * @param alias エイリアス
     * @since 2.0
     */
    public HFileWriter(HFile hFile, boolean directoryFlg, String alias) {
        this(hFile, directoryFlg, alias, -1);
    }    

    /**
     * ファイル出力（書込み）オブジェクトを生成します。
     * 指定した桁数のシーケンス番号の付加を行います。
     * <br><br>
     * 桁数は1以上を指定する必要があり、負の値を指定すると桁数指定がされないのと同様、
     * 0を指定するとシーケンス番号の付加が無効となります。
     * 
     * @param filePath 作成ファイルパス
     * @param directoryFlg ディレクトリを自動生成する場合はtrue、そうでなければfalse
     * @param alias エイリアス
     * @param digit 付加するシーケンス番号の桁数
     * @throws IOException filePath不正
     * @since 2.0
     */
    public HFileWriter(String filePath, boolean directoryFlg, String alias, int digit) throws IOException {
        this(new HFile(filePath), directoryFlg, alias, digit);
    }    

    /**
     * ファイル出力（書込み）オブジェクトを生成します。
     * 指定した桁数のシーケンス番号の付加を行います。
     * <br><br>
     * 桁数は1以上を指定する必要があり、負の値を指定すると桁数指定がされないのと同様、
     * 0を指定するとシーケンス番号の付加が無効となります。
     * 
     * @param hFile 作成ファイルのHFileオブジェクト
     * @param directoryFlg ディレクトリを自動生成する場合はtrue、そうでなければfalse
     * @param alias エイリアス
     * @param digit 付加するシーケンス番号の桁数
     * @since 2.0
     */
    public HFileWriter(HFile hFile, boolean directoryFlg, String alias, int digit) {
        if(hFile == null){
            throw new NullPointerException("HFile-object is null.");
        }
        this.hFile = hFile;
        this.directoryFlg = directoryFlg;
        this.alias = alias;
        this.digit = digit;
    }

    /**
     * 指定したストリームのデータをファイルに書き込みます。
     * ファイルはオブジェクト生成時にコンストラクタで指定したファイルです。
     * 
     * @param is 入力ストリーム
     * @throws IOException
     *          書込みに失敗した場合
     * @since 2.0
     */
    public void write(InputStream is) throws IOException {
        try {
            makeOutputFile();
        } catch (IOException e) {
            throw e;
        }
        if (directoryFlg) {
            makeDirectory();
        }
        // 出力ストリームを作成し、データを取得・作成
        FileOutputStream fos = new FileOutputStream(hFile);
        try {
            write(is, fos);
        } finally {
            if(fos != null){
                fos.close();
            }            
        }
    }

    /**
     * データを書き込む際にディレクトリを作成します。
     * 必要に応じてオーバーライドしてください。
     * 
     * @since 2.0
     */
    protected void makeDirectory(){
        File directory = hFile.getParentFile();
        if (directory != null) {
            if (!directory.exists()) {
                directory.mkdirs();
            }
        }
    }

    /**
     * データを書き込むための新規出力ファイルオブジェクト作成のためのロジックを定義します。
     * 必要に応じてオーバーライドしてください。
     * 
     * @throws IOException 新規出力ファイルのパスが不正となる場合
     * @since 2.0
     */
    protected void makeOutputFile() throws IOException {        
        String outputFilePath = null;        
        if (digit <= -1) {
            outputFilePath = hFile.getOtherFileName(alias);
        } else {
            outputFilePath = hFile.getOtherFileName(alias, digit);
        }
        hFile = new HFile(outputFilePath);
    }

//    /**
//     * 設定してあるストリームのデータをファイルに書き込みます。
//     * ファイルはオブジェクト生成時にコンストラクタで指定したファイルです。
//     * 
//     * @throws IOException
//     *          書込みに失敗した場合
//     * @since 2.0
//     */
//    public void write() throws IOException {
//        if (inputStream == null) {
//            throw new NullPointerException("Input-stream is null.");
//        }
//        write(inputStream);
//    }
//
//    /**
//     * ファイルに書き込む入力元のストリームを指定します。
//     * 
//     * @param is 入力ストリーム
//     * @since 2.0
//     */
//    public void setInputStream(InputStream is) {
//        this.inputStream = is;
//    }
//    
//    /**
//     * ファイルに書き込んだ入力元のストリームを閉じます。
//     * 
//     * @throws IOException
//     *          ストリームがクローズできなかった場合
//     * @since 2.0
//     */
//    public void close() throws IOException {
//        if (inputStream != null) {
//            inputStream.close();
//        }
//        inputStream = null;
//    }
}
