/*
 * blancoDb
 * Copyright (C) 2004-2005 Yasuo Nakanishi
 * 
 * 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;

import blanco.db.util.BlancoDbObjectStorage;
import blanco.ig.expander.Type;
import blanco.ig.expander.method.MethodExpander;

/**
 * @author Yasuo Nakanishi
 */
public class ExecuteMethod extends MethodExpander {
    private BlancoDbObjectStorage storage = null;

    public ExecuteMethod(final BlancoDbObjectStorage storage) {
        super("execute");
        this.storage = storage;
    }

    public void setupSignature() {
        // ランタイムパッケージの変化に対応。
        String runtimePackage = storage.getSetting().getRootNameSpace();
        if (storage.getSetting().getRuntimePackage() != null) {
            runtimePackage = storage.getSetting().getRuntimePackage();
        }

        final Type integrityConstraintException = new Type(runtimePackage
                + ".exception.IntegrityConstraintException");
        getJavaDoc().addException(integrityConstraintException,
                "データベース制約違反が発生した場合。");
        addException(integrityConstraintException);

        final Type deadlockException = new Type(runtimePackage
                + ".exception.DeadlockException");
        getJavaDoc().addException(deadlockException, "データベースデッドロックが発生した場合。");
        addException(deadlockException);

        final Type timeoutException = new Type(runtimePackage
                + ".exception.TimeoutException");
        getJavaDoc().addException(timeoutException, "データベースタイムアウトが発生した場合。");
        addException(timeoutException);

        getJavaDoc().addException(new Type("java.sql.SQLException"),
                "SQL例外が発生した場合。");
        addException(new Type("java.sql.SQLException"));

        getJavaDoc().addLine("ストアドプロシージャを実行します。<br>");

        getJavaDoc().addReturn("CallableStatement.executeメソッドの戻り値。");
        setReturnType(new Type("boolean"));
    }

    public void implement() {
        if (storage.getSetting().isLogging()) {
            getData().addLine("if (fLog.isDebugEnabled()) {");
            getData().addLine("fLog.debug(\"" + getName() + "\");");
            getData().addLine("}");
            getData().addLine("");
        }

        getData().addLine("if (fStatement == null) {");
        getData()
                .addLine(
                        "// CallableStatementが未取得の状態なので、CallableStatement.execute()実行に先立ちprepareCall()メソッドを呼び出して取得します。");
        getData().addLine("prepareCall();");
        getData().addLine("}");

        // 例外処理を含めて展開します。
        getData().addLine("");
        getData().addLine("// executeメソッドの実行結果については扱わないこととします。");
        getData().addLine("try {");
        getData().addLine("return fStatement.execute();");
        getData().addLine("} catch (SQLException ex) {");
        getData().addLine("throw BlancoDbUtil.convertToBlancoException(ex);");
        getData().addLine("}");
    }
}