/*
 * 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.caller.odp;

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.caller.CloseMethodDotNet;
import blanco.db.expander.query.field.LogFieldDotNet;
import blanco.db.expander.query.field.odp.ConnectionFieldOdpDotNet;
import blanco.db.expander.query.field.odp.StatementFieldOdpDotNet;
import blanco.db.expander.query.field.odp.TransactionFieldOdpDotNet;
import blanco.db.expander.query.iterator.odp.SetInputParameterMethodOdpDotNet;
import blanco.db.expander.query.odp.GetQueryMethodOdpDotNet;
import blanco.db.expander.query.odp.GetStatementMethodOdpDotNet;
import blanco.db.expander.query.odp.QueryConstructor2OdpDotNet;
import blanco.db.expander.query.odp.QueryConstructorOdpDotNet;
import blanco.dbmetadata.valueobject.BlancoDbMetaDataColumnStructure;

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

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

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

        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");
        fCgSourceFile.getImportList().add("Oracle.DataAccess.Types.*");

        fCgClass.getLangDoc().getDescriptionList().add("QueryCallerに属するクラスです。");
        fCgClass.getLangDoc().getDescriptionList().add(
                "呼出型SQL文をラッピングして各種アクセサを提供します。");

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

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

        new ConnectionFieldOdpDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new TransactionFieldOdpDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new StatementFieldOdpDotNet(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 QueryConstructorOdpDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();
        new QueryConstructor2OdpDotNet(fDbSetting, fSqlInfo, fCgFactory,
                fCgSourceFile, fCgClass).expand();

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

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

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

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

        for (int index = 0; index < fSqlInfo.getOutParameterList().size(); index++) {
            final BlancoDbMetaDataColumnStructure columnStructure = (BlancoDbMetaDataColumnStructure) fSqlInfo
                    .getOutParameterList().get(index);
            new GetCallerOutputParameterMethodOdpDotNet(fDbSetting, fSqlInfo,
                    fCgFactory, fCgSourceFile, fCgClass, columnStructure)
                    .expand();
        }

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

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

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

        return fCgSourceFile;
    }
}