/*
 * @(#)xcopy.java
 *
 * RID-X : XCOPY
 * コピー元のディレクトリの内容を、指定されてコピー先にコピーする
 *
 * @author  Intelligent Technology Inc.
 * @version 1.01 2002/01/31
 *
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 */

package jp.co.nri.rid.snapshot;

import java.io.*;
import java.util.*;
import java.text.*;
import java.net.URL;
import java.util.Random;


/**
 * コピー元のディレクトリの内容を、指定されてコピー先にコピーする
 */
public class xcopy {


/**
  * コンストラクタ
  *
  */
    public xcopy() {}

/**
  * XCOPY
  * コピー元のディレクトリの内容を、指定されてコピー先にコピーする
  *
  * @param  String      source          コピー元ディレクトリ
  * @param  String      destination     コピー先ディレクトリ
  *
  * @return boolean     true(成功) / false (失敗)
  */
    public boolean copy(String source, String destination) throws Exception {
        return directory(source, destination);
    }


/**
  * ディレクトリをコピーする（サブディレクトリも）
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    public boolean directory(String source, String destination) throws Exception {

        boolean ret = false;
        File source_file = new File(source);
        File destination_file = new File(destination);

        // ディレクトリの有無
        ret = source_file.exists();
        if (ret){

            //ディレクトリの生成／日付変更
            ret = makeDir(destination);
            if (ret) destination_file.setLastModified(source_file.lastModified());

            // ファイルおよびディレクトリのリストを取得
            String[] source_lst =  source_file.list();

            //ファイルまたはサブディレクトリを削除
            for (int n = 0; n < source_lst.length; n++) {
                ret = movement(source,  destination, source_lst[n]);
            }
        }
        return ret;
    }

/**
  * ファイルをコピーする
  *
  * @param  String      source          移動元ファイル名
  * @param  String      destination     移動先ファイル名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    public boolean file(String source_filename, String destination_filename) throws IOException {


        boolean ret = false;
        File source_file = new File(source_filename);
        File destination_file = new File(destination_filename);
        FileInputStream  source = null;
        FileOutputStream destination = null;
        byte[] buffer = new byte[1024];
        int bytes_read;

        try {
            /* コピー元ファイルの存在/ファイル/読込み判断 */
            if (!source_file.exists() || !source_file.isFile() || !source_file.canRead()) { return false; }

            /* ファイルコピー (1024バイト毎コピーする) */
            source      = new FileInputStream(source_file);
            destination = new FileOutputStream(destination_file);

            while(true) {
                bytes_read = source.read(buffer);
                if (bytes_read == -1 ) break;
                destination.write(buffer, 0, bytes_read);
            }
        }

        finally {
            /* クロース */
            if (source != null) source.close();
            if (destination != null) destination.close();
        }

        // 日付を変更
        destination_file.setLastModified(source_file.lastModified());

        return true;
    }

/**
  *   ファイル／ディレクトリの判断を行い、コピーする
  *
  * @param  String      source          移動元ディレクトリ名
  * @param  String      destination     移動先ディレクトリ名
  * @param  String      filename        ファイル名
  *
  * @return boolean     true(成功) / false (失敗)
  */
    private boolean movement(String source, String destination, String filename) throws Exception {

        boolean ret = false;

        String source_name      = source + File.separator + filename;
        String destination_name = destination + File.separator + filename;

        File source_file = new File(source_name);
        File destination_file = new File(destination_name);

        //存在確認
        ret = source_file.exists();
        if (ret) {
            // ディレクトリの場合
            if (source_file.isDirectory()) {
                //ディレクトリの生成
                ret = directory(source_name, destination_name);
            } else if (source_file.isFile()) {
                // ファイルコピー
                ret = file(source_name, destination_name);
            }
            
        }
        return ret;
    }

/**
  * ディレクトリの存在チェツク、存在しない場合は生成する
  *
  * @param  String      str_dir         ディレクトリ文字列
  * @return File        Fileクラス
  * @return boolean true(成功) / false (失敗)
  */
    public boolean makeDir(String str_dir) throws Exception {

        boolean ret = false;

        // Dir の存在チェック 存在しない場合は生成
        File dir = new File(str_dir);
        if (!dir.exists())
            ret = dir.mkdirs();
        else
            ret = true;

        return ret;
   }

/**
  * 指定されたファイルが存在するか
  *
  * @param String   source_name     コピー元
  * @return boolean true(存在する) / false (存在しない)
  */
    public boolean fileExists(String filename) {

        // 宣言
        File file = new File(filename);

        // 指定されたファイルが存在するか
        return file.exists();
    }

}