/*
 * blanco Framework
 * Copyright (C) 2004-2005 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.Iterator;

import blanco.commons.util.BlancoNameAdjuster;
import blanco.db.definition.QueryIteratorDotNet;
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.ResultSetFieldDotNet;
import blanco.db.expander.query.field.StatementFieldDotNet;
import blanco.db.expander.query.field.TransactionFieldDotNet;
import blanco.db.util.BlancoDbObjectStorageDotNet;
import blanco.ig.expander.ClassExpander;
import blanco.ig.expander.IgType;
import blanco.ig.expander.field.FieldExpander;
import blanco.ig.expander.implementor.IgStatement;

/**
 * @author Yasuo Nakanishi
 */
public class QueryIteratorClassDotNet extends ClassExpander {
    private BlancoDbObjectStorageDotNet storage = null;

    private QueryIteratorDotNet _iterator = null;

    public QueryIteratorClassDotNet(final BlancoDbObjectStorageDotNet storage,
            final IgType type, final QueryIteratorDotNet iterator) {
        super(type);
        _iterator = iterator;
        this.storage = storage;

        addImport(new IgType("System.String"));

        getJavaDoc().addLine(type.getName() + "クラス");
        getJavaDoc().addLine("QueryIteratorに属するクラスです。");
        getJavaDoc().addLine("検索型SQL文をラッピングして各種アクセサを提供します。");
        if (iterator.isSingle()) {
            getJavaDoc().addLine("シングル属性: 有効 (期待する処理件数は1件)");
        }
    }

    protected void expandClassStruct() {
        addField(new ConnectionFieldDotNet());
        // .NET Frameworkの場合にはトランザクションオブジェクトが必要です。
        addField(new TransactionFieldDotNet());
        addField(new StatementFieldDotNet());
        addField(new ResultSetFieldDotNet());

        if (storage.getSetting().isLogging()) {
            addImport(new IgType("org.apache.commons.logging.LogFactory"));
            final FieldExpander field1 = new FieldExpander(new IgType(
                    "org.apache.commons.logging.Log"), "fLog") {
                protected boolean isStatic() {
                    return true;
                }
            };
            field1.getJavaDoc().addLine("ロギングのためのオブジェクト");
            field1.getJavaDoc().addLine("※static finalの状態で維持されます");
            field1.setDefaultStatement(new IgStatement("LogFactory.getLog("
                    + getName() + ".class)"));
            addField(field1);
        }

        final IgType _type = new IgType(storage.getSetting().getRootNameSpace()
                + ".query", BlancoNameAdjuster.toClassName(_iterator.getName())
                + "Iterator");

        addMethod(new QueryConstructorDotNet(_type));
        addMethod(new QueryConstructor2DotNet(_type));

        addMethod(new GetQueryMethodDotNet(_iterator.getQuery()));

        addMethod(new PrepareStatementMethodDotNet(storage));
        addMethod(new PrepareStatementMethod2DotNet(storage, _iterator));
        // パラメータがある場合にのみ bindメソッドを生成します。
        Iterator iParameter = _iterator.getInParameterIterator();
        if (iParameter.hasNext()) {
            addMethod(new SetInputParameterMethodDotNet(storage, _iterator));
        }

        addMethod(new ExecuteQueryMethodDotNet(storage, _iterator));

        addMethod(new NextMethodDotNet(storage, _iterator));

        // カーソル属性がtrueの際には previousメソッドなどの
        // スクロールカーソル関連メソッドを追加生成
        // 前提: カーソル属性がtrueの場合にはsingle属性はfalse
        // DotNetでは双方向スクロールカーソルはサポートされません。

        final IgType rowObjectType = new IgType(storage.getSetting()
                .getRootNameSpace()
                + ".row", BlancoNameAdjuster.toClassName(_iterator.getName())
                + "Row");

        addMethod(new GetRowMethodDotNet(storage, rowObjectType, _iterator));

        if (_iterator.isSingle()) {
            addMethod(new GetSingleRowMethodDotNet(storage, rowObjectType,
                    _iterator));
        }

        if (_iterator.isSingle() == false) {
            addMethod(new GetListMethodDotNet(_iterator));
        }

        addMethod(new GetStatementMethodDotNet(storage));
        addMethod(new GetResultSetMethodDotNet(storage));

        addMethod(new CloseMethodDotNet(storage));

        addMethod(new FinalizeDotNet(storage, getName()));
    }
}