${database.allClassCopyright}package ${glPackageBaseCommon};

import javax.sql.DataSource;

import com.google.inject.AbstractModule;
import org.seasar.dbflute.BehaviorSelector;
import org.seasar.dbflute.bhv.core.BehaviorCommandInvoker;
import org.seasar.dbflute.bhv.core.CommonColumnAutoSetupper;
import org.seasar.dbflute.bhv.core.InvokerAssistant;
import ${glPackageExtendedBhv}.*;

/**
 * @author ${database.classAuthor}
 */
public class ${glDBFluteModule} extends AbstractModule {

    protected DataSource dataSource;

    public ${glDBFluteModule}(DataSource dataSource) {
        if (dataSource == null) {
            String msg = "The argument 'dataSource' should not be null!";
            throw new IllegalArgumentException(msg);
        }
        this.dataSource = dataSource;
    }

    @Override
    protected void configure() {
        new ${glDBFluteInitializer}(); // Initialize!

        // The components of DBFlute Runtime.
        ${glImplementedBehaviorSelector} behaviorSelector = new ${glImplementedBehaviorSelector}();
        BehaviorCommandInvoker behaviorCommandInvoker = new BehaviorCommandInvoker();
        ${glImplementedInvokerAssistant} invokerAssistant = createImplementedInvokerAssistant(behaviorCommandInvoker);
        behaviorCommandInvoker.setInvokerAssistant(invokerAssistant);
        ${glImplementedCommonColumnAutoSetupper} commonColumnAutoSetupper = createImplementedCommonColumnAutoSetupper();

        bind(BehaviorSelector.class).toInstance(behaviorSelector);
        bind(BehaviorCommandInvoker.class).toInstance(behaviorCommandInvoker);
        bind(InvokerAssistant.class).toInstance(invokerAssistant);
        bind(CommonColumnAutoSetupper.class).toInstance(commonColumnAutoSetupper);

        // The components of Behavior.
        setupBehavior(behaviorCommandInvoker, behaviorSelector, commonColumnAutoSetupper);
    }

    protected ${glImplementedInvokerAssistant} createImplementedInvokerAssistant(BehaviorCommandInvoker behaviorCommandInvoker) {
#if ($database.hasExtendedImplementedInvokerAssistantClass())
        ${glImplementedInvokerAssistant} invokerAssistant = new ${database.extendedImplementedInvokerAssistantClass}();
#else
        ${glImplementedInvokerAssistant} invokerAssistant = new ${glImplementedInvokerAssistant}();
#end
        invokerAssistant.setBehaviorCommandInvoker(behaviorCommandInvoker);
        invokerAssistant.setDataSource(dataSource);
        return invokerAssistant;
    }

    protected ${glImplementedCommonColumnAutoSetupper} createImplementedCommonColumnAutoSetupper() {
#if ($database.hasExtendedImplementedCommonColumnAutoSetupperClass())
        return new ${database.extendedImplementedCommonColumnAutoSetupperClass}();
#else
        return new ${glImplementedCommonColumnAutoSetupper}();
#end
    }

    protected void setupBehavior(BehaviorCommandInvoker ker, BehaviorSelector tor, CommonColumnAutoSetupper per) {
#foreach ($table in $database.tables)
        {
            ${table.extendedBehaviorClassName} bhv = new ${table.extendedBehaviorClassName}();
#if ($table.isWritable())
            bhv.setBehaviorCommandInvoker(ker); bhv.setBehaviorSelector(tor); bhv.setCommonColumnAutoSetupper(per);
#else
            bhv.setBehaviorCommandInvoker(ker); bhv.setBehaviorSelector(tor);
#end
            bind(${table.extendedBehaviorClassName}.class).toInstance(bhv);
        }
#end
    }
}
