/*
 * blancoDb Enterprise Edition
 * Copyright (C) 2005 Tosiki Iga
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.db.task;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.xml.sax.SAXException;

import blanco.db.conf.BlancoDbDatabaseConnectionSettingDef;
import blanco.db.exception.BlancoDbException;
import blanco.db.helper.BlancoDbDefaultGenerator;
import blanco.db.helper.BlancoDbExcel2Xml;
import blanco.db.helper.BlancoDbTableGateway2Xml;

/**
 * BlancoDb Ant Task
 */
public class BlancoDbTask extends Task {
    private String jdbcdriver = null;

    private String jdbcurl = null;

    private String jdbcuser = null;

    private String jdbcpassword = null;

    private String metadir = null;

    private String tmpdir = null;

    private String targetdir = null;

    private String basepackage = null;

    private String schema = null;

    private String table = null;

    private String sql = null;

    private boolean supportoldversiontablegateway = false;

    /**
     * @return basepackage を戻します。
     */
    public String getBasepackage() {
        return basepackage;
    }

    /**
     * @param basepackage
     *            basepackage を設定。
     */
    public void setBasepackage(String basepackage) {
        this.basepackage = basepackage;
    }

    /**
     * @return jdbcdriver を戻します。
     */
    public String getJdbcdriver() {
        return jdbcdriver;
    }

    /**
     * @param jdbcdriver
     *            jdbcdriver を設定。
     */
    public void setJdbcdriver(String jdbcdriver) {
        this.jdbcdriver = jdbcdriver;
    }

    /**
     * @return jdbcpassword を戻します。
     */
    public String getJdbcpassword() {
        return jdbcpassword;
    }

    /**
     * @param jdbcpassword
     *            jdbcpassword を設定。
     */
    public void setJdbcpassword(String jdbcpassword) {
        this.jdbcpassword = jdbcpassword;
    }

    /**
     * @return jdbcurl を戻します。
     */
    public String getJdbcurl() {
        return jdbcurl;
    }

    /**
     * @param jdbcurl
     *            jdbcurl を設定。
     */
    public void setJdbcurl(String jdbcurl) {
        this.jdbcurl = jdbcurl;
    }

    /**
     * @return jdbcuser を戻します。
     */
    public String getJdbcuser() {
        return jdbcuser;
    }

    /**
     * @param jdbcuser
     *            jdbcuser を設定。
     */
    public void setJdbcuser(String jdbcuser) {
        this.jdbcuser = jdbcuser;
    }

    /**
     * @return metadir を戻します。
     */
    public String getMetadir() {
        return metadir;
    }

    /**
     * @param metadir
     *            metadir を設定。
     */
    public void setMetadir(String metadir) {
        this.metadir = metadir;
    }

    /**
     * @return schema を戻します。
     */
    public String getSchema() {
        return schema;
    }

    /**
     * @param schema
     *            schema を設定。
     */
    public void setSchema(String schema) {
        this.schema = schema;
    }

    /**
     * @return supportoldversiontablegateway を戻します。
     */
    public boolean isSupportoldversiontablegateway() {
        return supportoldversiontablegateway;
    }

    /**
     * @param supportoldversiontablegateway
     *            supportoldversiontablegateway を設定。
     */
    public void setSupportoldversiontablegateway(
            boolean supportoldversiontablegateway) {
        this.supportoldversiontablegateway = supportoldversiontablegateway;
    }

    public void execute() throws BuildException {
        System.out.println("blancoDb タスク");
        if (jdbcdriver == null) {
            throw new BuildException("jdbcdriverを指定してください。");
        }
        if (jdbcurl == null) {
            throw new BuildException("jdbcurlを指定してください。");
        }
        if (jdbcuser == null) {
            throw new BuildException("jdbcuserを指定してください。");
        }
        if (jdbcpassword == null) {
            throw new BuildException("jdbcpasswordを指定してください。");
        }
        if (metadir == null) {
            throw new BuildException("metadirを指定してください。");
        }
        if (basepackage == null) {
            throw new BuildException("basepackageを指定してください。");
        }
        if (tmpdir == null) {
            // テンポラリフォルダの指定がない場合には、カレント直下のtmpを用います。
            tmpdir = "tmp";
        }
        try {
            File blancoSqlDirectory = new File(getMetadir());
            File blancoTmpDbTableDirectory = new File(tmpdir + "/db/table");
            File blancoTmpDbSqlDirectory = new File(tmpdir + "/db/sql");
            blancoTmpDbTableDirectory.mkdirs();
            blancoTmpDbSqlDirectory.mkdirs();

            BlancoDbDatabaseConnectionSettingDef connDef = new BlancoDbDatabaseConnectionSettingDef();
            connDef.setJdbcDriver(getJdbcdriver());
            connDef.setJdbcUrl(getJdbcurl());
            connDef.setJdbcUser(getJdbcuser());
            connDef.setJdbcPassword(getJdbcpassword());

            if (getSchema() != null) {
                // スキーマ名を指定。
                connDef.setSchema(getSchema());
            }

            if (getTable() == null || getTable().equals("true")) {
                // SimpleTableGatewayを自動生成
                BlancoDbTableGateway2Xml gateway2xml = new BlancoDbTableGateway2Xml() {
                    public boolean progress(int progressCurrent,
                            int progressTotal, String progressItem) {
                        // 常にtrueを返します。
                        return true;
                    }
                };
                gateway2xml
                        .setSupportOldVersionTableGateway(isSupportoldversiontablegateway());
                gateway2xml.process(connDef, blancoTmpDbTableDirectory);

                // XMLファイルを元にR/Oマッピングを自動生成
                BlancoDbDefaultGenerator generator = new BlancoDbDefaultGenerator() {
                    public boolean progress(int progressCurrent,
                            int progressTotal, String progressItem) {
                        // 常にtrueを返します。
                        return true;
                    }
                };
                generator
                        .setSupportOldVersionTableGateway(isSupportoldversiontablegateway());
                generator.process(connDef, blancoTmpDbTableDirectory,
                        getBasepackage(), getTargetdir());
            }

            if (getSql() == null || getSql().equals("true")) {
                // ExcelファイルからXMLファイルを自動生成します。
                // new BlancoDbExcel2Xml(new File(BLANCO_SQL_DIRECTORY),
                // blancoSqlDirectory).processAllFiles();
                new BlancoDbExcel2Xml(blancoSqlDirectory,
                        blancoTmpDbSqlDirectory) {
                    public boolean progress(int progressCurrent,
                            int progressTotal, String progressItem) {
                        // 常にtrueを返します。
                        return true;
                    }
                }.processAllFiles();

                // XMLファイルを元にR/Oマッピングを自動生成
                BlancoDbDefaultGenerator generator = new BlancoDbDefaultGenerator() {
                    public boolean progress(int progressCurrent,
                            int progressTotal, String progressItem) {
                        // 常にtrueを返します。
                        return true;
                    }
                };
                generator
                        .setSupportOldVersionTableGateway(isSupportoldversiontablegateway());
                generator.process(connDef, blancoTmpDbSqlDirectory,
                        getBasepackage(), getTargetdir());
            }
        } catch (SQLException e) {
            throw new BuildException("ビルド時に例外が発生: ビルドを中断します: " + e.toString());
        } catch (SAXException e) {
            throw new BuildException("ビルド時に例外が発生: ビルドを中断します: " + e.toString());
        } catch (IOException e) {
            throw new BuildException("ビルド時に例外が発生: ビルドを中断します: " + e.toString());
        } catch (ParserConfigurationException e) {
            throw new BuildException("ビルド時に例外が発生: ビルドを中断します: " + e.toString());
        } catch (BlancoDbException e) {
            throw new BuildException("ビルド時に例外が発生: ビルドを中断します: " + e.toString());
        }
    }

    public String getTargetdir() {
        return targetdir;
    }

    public void setTargetdir(String targetdir) {
        this.targetdir = targetdir;
    }

    /**
     * @return Returns the sql.
     */
    public final String getSql() {
        return sql;
    }

    /**
     * @param sql
     *            The sql to set.
     */
    public final void setSql(String sql) {
        this.sql = sql;
    }

    /**
     * @return Returns the table.
     */
    public final String getTable() {
        return table;
    }

    /**
     * @param table
     *            The table to set.
     */
    public final void setTable(String table) {
        this.table = table;
    }

    public String getTmpdir() {
        return tmpdir;
    }

    public void setTmpdir(String tmpdir) {
        this.tmpdir = tmpdir;
    }
}
