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

import java.util.List;

import blanco.cg.BlancoCgObjectFactory;
import blanco.cg.valueobject.BlancoCgClass;
import blanco.cg.valueobject.BlancoCgMethod;
import blanco.cg.valueobject.BlancoCgSourceFile;
import blanco.commons.util.BlancoNameAdjuster;
import blanco.commons.util.BlancoNameUtil;
import blanco.db.common.expander.BlancoDbAbstractMethod;
import blanco.db.common.util.BlancoDbUtil;
import blanco.db.common.valueobject.BlancoDbSetting;
import blanco.db.common.valueobject.BlancoDbSqlInfoStructure;
import blanco.db.expander.exception.NoRowFoundExceptionClassDotNet;
import blanco.db.expander.exception.TooManyRowsFoundExceptionClassDotNet;
import blanco.db.util.BlancoDbCgUtilDotNet;

/**
 * 個別のメソッドを展開するためのクラス。
 * 
 * シングル属性がtrueの場合にのみ、このクラスは利用されます
 * 
 * @author Tosiki Iga
 */
public class GetSingleRowMethodDotNet extends BlancoDbAbstractMethod {
    public GetSingleRowMethodDotNet(final BlancoDbSetting argDbSetting,
            final BlancoDbSqlInfoStructure argSqlInfo,
            final BlancoCgObjectFactory argCgFactory,
            final BlancoCgSourceFile argCgSourceFile,
            final BlancoCgClass argCgClass) {
        super(argDbSetting, argSqlInfo, argCgFactory, argCgSourceFile,
                argCgClass);
    }

    public void expand() {
        final BlancoCgMethod cgMethod = fCgFactory.createMethod("GetSingleRow",
                "現在の行のデータをオブジェクトとして取得します。");
        fCgClass.getMethodList().add(cgMethod);

        // 行オブジェクトの型名を取得します。
        final String rowObjectType = fDbSetting.getBasePackage() + ".row."
                + BlancoNameAdjuster.toClassName(fSqlInfo.getName()) + "Row";

        cgMethod.setReturn(fCgFactory.createReturn(rowObjectType, "行オブジェクト"));

        // cgMethod.getThrowList().add(
        // fCgFactory.createException(BlancoDbUtil
        // .getRuntimePackage(fDbSetting)
        // + ".exception.NoRowFoundException",
        // "データベースの処理の結果、1行もデータが検索されなかった場合。"));
        // cgMethod.getThrowList().add(
        // fCgFactory.createException(BlancoDbUtil
        // .getRuntimePackage(fDbSetting)
        // + ".exception.TooManyRowsFoundException",
        // "データベースの処理の結果、1行を超えるデータが検索されてしまった場合。"));

        BlancoDbCgUtilDotNet.addExceptionToMethodSqlException(fCgFactory,
                cgMethod);

        final List<String> listDesc = cgMethod.getLangDoc()
                .getDescriptionList();

        listDesc.add("このメソッドを利用する場合には、Next()などのカーソルを操作するメソッドとは併用しないでください。");
        listDesc.add("");
        listDesc.add("single属性が有効");
        listDesc.add("検索結果が1件以外の場合には、NotSingleRowExceptionクラスを");
        listDesc.add("派生したクラスの例外が発生します。");

        final List<String> listLine = cgMethod.getLineList();

        if (fDbSetting.getLogging()) {
            BlancoDbCgUtilDotNet.addBeginLogToMethod(cgMethod);
        }

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

        listLine.add("if (Next() == false) {");
        listLine.add("throw new NoRowFoundException(\"行が検索できませんでした。\");");
        listLine.add("}");
        listLine.add("");

        listLine.add(BlancoNameUtil.trimJavaPackage(rowObjectType)
                + " result = GetRow();");
        listLine.add("");

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

        // 1行を超えて変更があったかどうかをチェック。
        listLine.add("if (Next()) {");
        listLine
                .add("throw new TooManyRowsFoundException(\"1件以上の行が検索されました。\");");
        listLine.add("}");
        listLine.add("");

        listLine.add("return result;");
    }
}