/*
 * blanco Framework
 * Copyright (C) 2004-2006 IGA Tosiki
 * 
 * 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.expander.query.invoker;

import blanco.cg.BlancoCgObjectFactory;
import blanco.cg.valueobject.BlancoCgSourceFile;
import blanco.commons.util.BlancoNameAdjuster;
import blanco.db.common.expander.BlancoDbAbstractClass;
import blanco.db.common.util.BlancoDbUtil;
import blanco.db.common.valueobject.BlancoDbSetting;
import blanco.db.common.valueobject.BlancoDbSqlInfoStructure;
import blanco.db.expander.query.FinalizeDotNet;
import blanco.db.expander.query.GetQueryMethodDotNet;
import blanco.db.expander.query.GetStatementMethodDotNet;
import blanco.db.expander.query.PrepareStatementMethod2DotNet;
import blanco.db.expander.query.PrepareStatementMethodDotNet;
import blanco.db.expander.query.QueryConstructor2DotNet;
import blanco.db.expander.query.QueryConstructorDotNet;
import blanco.db.expander.query.field.ConnectionFieldDotNet;
import blanco.db.expander.query.field.LogFieldDotNet;
import blanco.db.expander.query.field.StatementFieldDotNet;
import blanco.db.expander.query.field.TransactionFieldDotNet;
import blanco.db.expander.query.iterator.SetInputParameterMethodDotNet;

/**
 * 個別のクラスを展開するためのクラス。
 */
public class QueryInvokerClassDotNet extends BlancoDbAbstractClass {

    public QueryInvokerClassDotNet(final BlancoDbSetting argDbSetting,
            final BlancoDbSqlInfoStructure argSqlInfo,
            final BlancoCgObjectFactory argCgFactory) {
        super(argDbSetting, argSqlInfo, argCgFactory);
    }

    public BlancoCgSourceFile expand() {
        final String className = BlancoNameAdjuster.toClassName(fSqlInfo
                .getName())
                + "Invoker";

        fCgSourceFile = fCgFactory.createSourceFile(fDbSetting.getBasePackage()
                + ".query", "This code is generated by blanco Framework.");
        fCgClass = fCgFactory.createClass(className, className + "クラス");
        fCgSourceFile.getClassList().add(fCgClass);

        // TODO 旧バージョンとの互換性。有無を言わさず利用することとする。
        fCgSourceFile.getImportList().add("System.Data.SqlDbType");

        fCgClass.getLangDoc().getDescriptionList()
                .add("QueryInvokerに属するクラスです。");
        fCgClass.getLangDoc().getDescriptionList().add(
                "実行型SQL文をラッピングして各種アクセサを提供します。");
        if (fSqlInfo.getSingle()) {
            fCgClass.getLangDoc().getDescriptionList().add(
                    "シングル属性: 有効 (期待する処理件数は1件)");
        }

        fCgSourceFile.getImportList().add(
                BlancoDbUtil.getRuntimePackage(fDbSetting)
                        + ".exception.IntegrityConstraintException");

        // BlancoDbUtilは常にインポートします。
        fCgSourceFile.getImportList().add(
                BlancoDbUtil.getRuntimePackage(fDbSetting)
                        + ".util.BlancoDbUtil");

        new ConnectionFieldDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new TransactionFieldDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new StatementFieldDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

        if (fDbSetting.getLogging()) {
            fCgSourceFile.getImportList().add(
                    "org.apache.commons.logging.LogFactory");
            new LogFieldDotNet(fDbSetting, fSqlInfo, fCgFactory, fCgSourceFile,
                    fCgClass).expand();
        }

        new QueryConstructorDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new QueryConstructor2DotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new GetQueryMethodDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

        new PrepareStatementMethodDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        // t.iga
        new PrepareStatementMethod2DotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

        // 入力パラメータがある場合にのみbindします。
        if (fSqlInfo.getInParameterList().size() > 0) {
            new SetInputParameterMethodDotNet(fDbSetting, fSqlInfo, fCgFactory,
                    fCgSourceFile, fCgClass, false).expand();
        }
        new ExecuteUpdateMethodDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        if (fSqlInfo.getSingle()) {
            new ExecuteSingleUpdateMethodDotNet(fDbSetting, fSqlInfo,
                    fCgFactory, fCgSourceFile, fCgClass).expand();
        }

        new GetStatementMethodDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

        new CloseMethodDotNet(fDbSetting, fSqlInfo, fCgFactory, fCgSourceFile,
                fCgClass).expand();

        new FinalizeDotNet(fDbSetting, fSqlInfo, fCgFactory, fCgSourceFile,
                fCgClass).expand();

        return fCgSourceFile;
    }
}