/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.extension.jdbc.gen.internal.command; import java.sql.Connection; import java.sql.DatabaseMetaData; import org.seasar.extension.jdbc.JdbcManager; import org.seasar.extension.jdbc.gen.ProductInfo; import org.seasar.extension.jdbc.gen.command.Command; import org.seasar.extension.jdbc.gen.dialect.GenDialect; import org.seasar.extension.jdbc.gen.dialect.GenDialectRegistry; import org.seasar.extension.jdbc.gen.exception.CommandFailedRuntimeException; import org.seasar.extension.jdbc.gen.internal.factory.Factory; import org.seasar.extension.jdbc.gen.internal.factory.FactoryImpl; import org.seasar.extension.jdbc.gen.internal.util.ReflectUtil; import org.seasar.extension.jdbc.gen.internal.util.SingletonS2ContainerFactorySupport; import org.seasar.extension.jdbc.manager.JdbcManagerImplementor; import org.seasar.extension.jdbc.util.ConnectionUtil; import org.seasar.extension.jdbc.util.DataSourceUtil; import org.seasar.extension.jdbc.util.DatabaseMetaDataUtil; import org.seasar.framework.beans.BeanDesc; import org.seasar.framework.beans.PropertyDesc; import org.seasar.framework.beans.factory.BeanDescFactory; import org.seasar.framework.container.SingletonS2Container; import org.seasar.framework.container.factory.SingletonS2ContainerFactory; import org.seasar.framework.log.Logger; /** * コマンドの抽象クラスです。 * * @author taedium */ public abstract class AbstractCommand implements Command { /** 設定ファイルのパス */ protected String configPath = "s2jdbc.dicon"; /** 環境名 */ protected String env = "ut"; /** {@link JdbcManager}のコンポーネント名 */ protected String jdbcManagerName = "jdbcManager"; /** {@link Factory}の実装クラス名 */ protected String factoryClassName = FactoryImpl.class.getName(); /** {@link SingletonS2ContainerFactory}のサポート */ protected SingletonS2ContainerFactorySupport containerFactorySupport; /** 内部的なJDBCマネージャ */ protected JdbcManagerImplementor jdbcManager; /** S2JDBC-Genのインタフェースの実装を作成するファクトリ */ protected Factory factory; /** * インスタンスを構築します。 */ public AbstractCommand() { } /** * 設定ファイルのパスを返します。 * * @return 設定ファイルのパス */ public String getConfigPath() { return configPath; } /** * 設定ファイルのパスを設定します。 * * @param configPath * 設定ファイルのパス */ public void setConfigPath(String configPath) { this.configPath = configPath; } /** * 環境名を返します。 * * @return 環境名 */ public String getEnv() { return env; } /** * 環境名を設定します。 * * @param env * 環境名 */ public void setEnv(String env) { this.env = env; } /** * {@link JdbcManager}のコンポーネント名を返します。 * * @return {@link JdbcManager}のコンポーネント名 */ public String getJdbcManagerName() { return jdbcManagerName; } /** * {@link JdbcManager}のコンポーネント名を設定します。 * * @param jdbcManagerName * {@link JdbcManager}のコンポーネント名 */ public void setJdbcManagerName(String jdbcManagerName) { this.jdbcManagerName = jdbcManagerName; } /** * {@link Factory}の実装クラス名を返します。 * * @return {@link Factory}の実装クラス名 */ public String getFactoryClassName() { return factoryClassName; } /** * {@link Factory}の実装クラス名を設定します。 * * @param factoryClassName * {@link Factory}の実装クラス名 */ public void setFactoryClassName(String factoryClassName) { this.factoryClassName = factoryClassName; } public final void execute() { ProductInfo info = ProductInfo.getInstance(); getLogger().log("IS2JDBCGen0008", new Object[] { info.getName(), info.getVersion() }); String commandClassName = getClass().getName(); getLogger().log("DS2JDBCGen0003", new Object[] { commandClassName }); logWritableProperties(); validate(); init(); try { doExecute(); } catch (Throwable t) { throw new CommandFailedRuntimeException(t, commandClassName); } finally { destroy(); } getLogger().log("DS2JDBCGen0008", new Object[] { commandClassName }); } /** * 設定可能なプロパティの値をログ出力します。 */ protected void logWritableProperties() { BeanDesc beanDesc = BeanDescFactory.getBeanDesc(getClass()); for (int i = 0; i < beanDesc.getPropertyDescSize(); i++) { PropertyDesc propertyDesc = beanDesc.getPropertyDesc(i); if (propertyDesc.hasWriteMethod()) { getLogger().log( "DS2JDBCGen0001", new Object[] { propertyDesc.getPropertyName(), propertyDesc.getValue(this) }); } } } /** * 検証します。 */ protected final void validate() { doValidate(); } /** * 初期化します。 */ protected final void init() { factory = ReflectUtil.newInstance(Factory.class, factoryClassName); containerFactorySupport = new SingletonS2ContainerFactorySupport( configPath, env); containerFactorySupport.init(); jdbcManager = SingletonS2Container.getComponent(jdbcManagerName); doInit(); } /** * 破棄します。 */ protected final void destroy() { doDestroy(); if (containerFactorySupport != null) { containerFactorySupport.destory(); } } /** * RDBMSとRDBMSに対する方言をログ出力します。 * * @param dialect */ protected void logRdbmsAndGenDialect(GenDialect dialect) { getLogger().log("DS2JDBCGen0005", new Object[] { getRdbmsName(), dialect.getClass().getName() }); } /** * RDBMSの名前を返します。 * * @return RDBMSの名前 */ protected String getRdbmsName() { Connection conn = DataSourceUtil.getConnection(jdbcManager .getDataSource()); try { DatabaseMetaData metaData = ConnectionUtil.getMetaData(conn); return DatabaseMetaDataUtil.getDatabaseProductName(metaData); } finally { ConnectionUtil.close(conn); } } /** * {@link GenDialect}の実装クラスを返します。 * * @param genDialectClassName * {@link GenDialect}の実装クラス名 * @return {@link GenDialect}の実装クラス */ protected GenDialect getGenDialect(String genDialectClassName) { if (genDialectClassName != null) { return ReflectUtil.newInstance(GenDialect.class, genDialectClassName); } return GenDialectRegistry.getGenDialect(jdbcManager.getDialect()); } /** * サブクラスで検証します。 */ protected abstract void doValidate(); /** * サブクラスで初期化します。 */ protected abstract void doInit(); /** * サブクラスで実行します。 * * @throws Throwable */ protected abstract void doExecute() throws Throwable; /** * サブクラスで破棄します。 */ protected abstract void doDestroy(); /** * ロガーを返します。 * * @return ロガー */ protected abstract Logger getLogger(); }