/**
 * blancoDbツール <br>
 * blancoDb XMLファイルの内容を検証するためのユーティリティプログラム <br>
 * 
 * @since 2005.05.13
 * @author Tosiki Iga
 */

package blanco.db.helper;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import blanco.db.BlancoDbConstants;
import blanco.db.collector.BlancoDbDatabaseConnection;
import blanco.db.collector.ExecuteQueryLoader;
import blanco.db.conf.BlancoDbDatabaseConnectionSettingDef;

/**
 * TableGatewayをリストアップするためのユーティリティクラス。 <br>
 * TODO: 列に空白付き文字が利用されている場合、適切に動作しない問題がわかっている。
 */
public class BlancoDbXmlValidator {

    public void process(BlancoDbDatabaseConnectionSettingDef connDef,
            File blancoSqlDirectory) throws SQLException {
        BlancoDbDatabaseConnectionSettingDef jdbc = new BlancoDbDatabaseConnectionSettingDef();
        jdbc.setJdbcDriver(connDef.getJdbcDriver());
        jdbc.setJdbcUrl(connDef.getJdbcUrl());
        jdbc.setJdbcUser(connDef.getJdbcUser());
        jdbc.setJdbcPassword(connDef.getJdbcPassword());
        jdbc.setSchema(connDef.getSchema());

        BlancoDbDatabaseConnection dbInfoCollector = new BlancoDbDatabaseConnection();
        try {
            dbInfoCollector.connect(connDef);
            dbInfoCollector.getDatabaseVersionInfo();

            if (blancoSqlDirectory != null) {
                // 指定がある場合にのみ SQL定義ファイル格納ディレクトリを処理します。
                File[] fileSettingXml = blancoSqlDirectory.listFiles();
                for (int index = 0; index < fileSettingXml.length; index++) {
                    if (fileSettingXml[index].getName().endsWith(".xml") == false) {
                        // ファイルの拡張子が xml であるもののみ処理します。
                        continue;
                    }
                    parseAndValidateBlancoDbSettingFile(blancoSqlDirectory
                            .getAbsolutePath(), fileSettingXml[index]);
                }
            }

        } finally {
            dbInfoCollector.close();
        }
    }

    /**
     * BlancoDb SQL定義ファイルをパース処理して、検証を行います。
     * 
     * @param fileSettingXml
     * @param metadata
     */
    private void parseAndValidateBlancoDbSettingFile(String directory,
            File fileSettingXml) {
        DocumentBuilderFactory documentFactory = DocumentBuilderFactory
                .newInstance();
        DocumentBuilder documentBuilder = null;
        Document document = null;
        try {
            documentBuilder = documentFactory.newDocumentBuilder();
        } catch (ParserConfigurationException ex1) {
            System.err.println("ドキュメント作成時に例外が発生しました.:" + ex1.toString());
            ex1.printStackTrace();
            return;
        }
        try {
            document = documentBuilder.parse(fileSettingXml);
        } catch (SAXException e) {
            System.err.println("ドキュメントパース時に例外が発生しました:" + e.toString());
            e.printStackTrace();
            return;
        } catch (IOException e) {
            System.err.println("ドキュメントパース時に例外が発生しました:" + e.toString());
            e.printStackTrace();
            return;
        }
        Element blancoDbElement = document.getDocumentElement();
        if (blancoDbElement == null) {
            System.out.println("blanco-dbルートノードが見つかりません");
            return;
        }
        NodeList rootNodeList = blancoDbElement.getChildNodes();
        if (rootNodeList == null) {
            return;
        }
        int length = rootNodeList.getLength();
        for (int indexNodeList = 0; indexNodeList < length; indexNodeList++) {
            Node node = rootNodeList.item(indexNodeList);
            if (node.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }
            Element eleCommandQuery = (Element) node;
            String nodeName = eleCommandQuery.getNodeName();
            if (nodeName.equals(BlancoDbConstants.QUERY_ITERATOR)) {
                System.out.println("検索型 クエリ名["
                        + eleCommandQuery.getAttribute("name") + "]");
                // TODO ここで検証
                //metadata.addSelectQuery(new SelectQuery(eleCommandQuery
                //      .getAttribute("name"), fileSettingXml.getName()));
            } else if (nodeName.equals(BlancoDbConstants.QUERY_INVOKER)) {
                System.out.println("実行型 クエリ名["
                        + eleCommandQuery.getAttribute("name") + "]");
                // TODO ここで検証
                ExecuteQueryLoader loader = new ExecuteQueryLoader(directory);
                // TODO 工事中！！！
                //loader.load(new
                // ExecuteQuery(eleCommandQuery.getAttribute("name"),
                //        fileSettingXml.getName()));
            }
        }
    }
}
