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

import java.sql.Connection;
import java.sql.PreparedStatement;

import blanco.db.conf.BlancoDbSetting;
import blanco.db.conf.Logging;
import blanco.db.definition.QueryInvoker;
import blanco.db.expander.log.OutLogMethod;
import blanco.db.expander.query.Finalize;
import blanco.db.expander.query.GetQueryMethod;
import blanco.db.expander.query.PrepareStatementMethod;
import blanco.db.expander.query.PrepareStatementMethod2;
import blanco.db.expander.query.QueryConstructor;
import blanco.db.generator.TypeFactory;
import blanco.db.properties.GenerationProperties;
import blanco.db.util.BlancoDbObjectStorage;
import blanco.ig.expander.ClassExpander;
import blanco.ig.expander.Type;
import blanco.ig.expander.Value;
import blanco.ig.expander.field.FieldExpander;
import blanco.ig.expander.field.PrivateField;
import blanco.ig.expander.implementor.Call;

/**
 * @author Yasuo Nakanishi
 */
public class QueryInvokerClass extends ClassExpander {
    private BlancoDbSetting _setting = null;

    private QueryInvoker _invoker = null;

    private TypeFactory _factory = null;

    private GenerationProperties _properties = null;

    public QueryInvokerClass(Type type, QueryInvoker invoker) {
        super(type);

        _invoker = invoker;

        BlancoDbObjectStorage storage = BlancoDbObjectStorage.getInstance();
        _setting = storage.getSetting();
        _factory = storage.getTypeFactory();
        _properties = storage.getGenerationProperties();

        if (_properties.isGenerateJavaDoc()) {
            getJavaDoc().addLine(type.getName() + "クラス<br>");
            getJavaDoc().addLine("QueryInvokerに属するクラスです。<br>");
            getJavaDoc().addLine("実行型SQL文をラッピングして各種アクセサを提供します。");
        }
    }

    protected void expandClassStruct() {
        addImport(new Type(_setting.getRootNameSpace() + ".util.BlancoDbUtil"));

        addField(new PrivateField(new Value(Connection.class, "connection")));
        addField(new PrivateField(new Value(PreparedStatement.class,
                "Statement")));

        if (_setting.getLogging().equals(Logging.LOG4J)) {
            Value logger = new Value(new Type("org.apache.log4j.Logger"),
                    "Logger");
            FieldExpander field = new PrivateField(logger);
            Call c = new Call(logger.getType(), "getLogger");
            c.addArgument(new Call("getClass"));
            field.setDefaultStatement(c);
            addField(field);
        }

        addMethod(new QueryConstructor(getType()));
        addMethod(new GetQueryMethod(_invoker.getQuery()));

        if (_setting.getLogging().equals(Logging.LOG4J)) {
            addMethod(new OutLogMethod());
        }

        addMethod(new PrepareStatementMethod());
        // t.iga
        addMethod(new PrepareStatementMethod2(null));

        // 入力パラメータがある場合にのみbindします。
        if (_invoker.getParameterIterator().hasNext()) {
            addMethod(new SetInvokerInputParameterMethod(_invoker));
        }
        addMethod(new ExecuteUpdateMethod(_invoker));
        if (_invoker.isSingle()) {
            addMethod(new ExecuteSingleUpdateMethod(_invoker));
        }
        addMethod(new CloseMethod());

        addMethod(new Finalize());
    }
}