${database.allClassCopyright}package ${glPackageBaseCommon}; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.SQLException; import java.sql.Timestamp; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.seasar.dbflute.DBDef; import org.seasar.dbflute.QLog; import org.seasar.dbflute.XLog; import org.seasar.dbflute.bhv.core.supplement.SequenceCacheKeyGenerator; import org.seasar.dbflute.bhv.outsidesql.factory.OutsideSqlExecutorFactory; import org.seasar.dbflute.cbean.sqlclause.SqlClauseCreator; import org.seasar.dbflute.dbmeta.name.SqlNameFilter; import org.seasar.dbflute.exception.IllegalDBFluteConfigAccessException; import org.seasar.dbflute.jdbc.DataSourceHandler; import org.seasar.dbflute.jdbc.NotClosingConnectionWrapper; import org.seasar.dbflute.jdbc.PhysicalConnectionDigger; import org.seasar.dbflute.jdbc.StatementConfig; import org.seasar.dbflute.jdbc.ValueType; import org.seasar.dbflute.s2dao.valuetype.TnValueTypes; import org.seasar.dbflute.s2dao.valuetype.plugin.OracleAgent; import org.seasar.dbflute.s2dao.valuetype.plugin.OracleDateType; import org.seasar.dbflute.s2dao.valuetype.plugin.OracleArrayType; import org.seasar.dbflute.s2dao.valuetype.plugin.OracleStructType; import org.seasar.dbflute.twowaysql.DisplaySqlBuilder; import org.seasar.dbflute.util.DfReflectionUtil; #if ($database.isTargetContainerSeasar()) import org.seasar.extension.dbcp.ConnectionWrapper; #end #if ($database.isTargetContainerSpring()) import org.springframework.jdbc.datasource.DataSourceUtils; #end /** * @author ${database.classAuthor} */ public class ${glDBFluteConfig} { // =================================================================================== // Definition // ========== /** Log instance. */ private static final Log _log = LogFactory.getLog(${glDBFluteConfig}.class); #if ($database.isOutsideSqlPackageValid()) /** The default package of outside SQL. The default value is '${database.outsideSqlPackage}'. */ private static final String DEFAULT_OUTSIDE_SQL_PACKAGE = "${database.outsideSqlPackage}"; #else /** The default package of outside SQL. */ private static final String DEFAULT_OUTSIDE_SQL_PACKAGE = null; #end #if ($database.isSqlLogRegistryValid()) /** The default value of whether it uses SQL Log Registry. The default value is true. */ private static final boolean DEFAULT_USE_SQL_LOG_REGISTRY = true; #else /** The default value of whether it uses SQL Log Registry. The default value is false. */ private static final boolean DEFAULT_USE_SQL_LOG_REGISTRY = false; #end /** Singleton instance. */ private static final ${glDBFluteConfig} _instance = new ${glDBFluteConfig}(); // =================================================================================== // Attribute // ========= // ----------------------------------------------------- // Configuration // ------------- protected StatementConfig _defaultStatementConfig; protected boolean _queryLogLevelInfo; protected boolean _executeStatusLogLevelInfo; protected String _logDateFormat; protected String _logTimestampFormat; protected DataSourceHandler _dataSourceHandler; protected PhysicalConnectionDigger _physicalConnectionDigger; protected SequenceCacheKeyGenerator _sequenceCacheKeyGenerator; protected SqlClauseCreator _sqlClauseCreator; protected SqlNameFilter _tableSqlNameFilter; protected String _outsideSqlPackage = DEFAULT_OUTSIDE_SQL_PACKAGE; protected OutsideSqlExecutorFactory _outsideSqlExecutorFactory; protected boolean _useSqlLogRegistry = DEFAULT_USE_SQL_LOG_REGISTRY; protected boolean _disableSelectIndex; protected boolean _internalDebug; // ----------------------------------------------------- // Database Dependency // ------------------- #if ($database.isAvailableDatabaseDependency()) #if ($database.isDatabasePostgreSQL()) protected org.seasar.dbflute.dbway.WayOfPostgreSQL.OperandOfLikeSearch _fullTextSearchOperand = org.seasar.dbflute.dbway.WayOfPostgreSQL.OperandOfLikeSearch.FULL_TEXT_SEARCH; #end #end // ----------------------------------------------------- // Lock // ---- protected boolean _locked = true; // at first locked // =================================================================================== // Constructor // =========== /** * Constructor. */ private ${glDBFluteConfig}() { // adjusts default settings _physicalConnectionDigger = new ImplementedPhysicalConnectionDigger(); if (isCurrentDBDef(DBDef.Oracle)) { // date formatting has two points: // o the DATE type of Oracle has seconds // o it uses a date literal of Oracle _logDateFormat = "timestamp $df:{yyyy-MM-dd HH:mm:ss}"; _logTimestampFormat = "timestamp $df:{" + DisplaySqlBuilder.DEFAULT_TIMESTAMP_FORMAT + "}"; } #if ($database.isDatabaseOracle() && $database.isAvailableDatabaseNativeJDBC()) // treats as uses Oracle date of database native JDBC to get best performances TnValueTypes.registerBasicValueType(DBDef.Oracle, java.util.Date.class, new ImplementedOracleDateType()); #end } // =================================================================================== // Singleton // ========= /** * Get singleton instance. * @return Singleton instance. (NotNull) */ public static ${glDBFluteConfig} getInstance() { return _instance; } // =================================================================================== // Default Statement Config // ======================== public StatementConfig getDefaultStatementConfig() { return _defaultStatementConfig; } public void setDefaultStatementConfig(StatementConfig defaultStatementConfig) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting defaultStatementConfig: " + defaultStatementConfig); } _defaultStatementConfig = defaultStatementConfig; } // =================================================================================== // Query Log Level Info // ==================== public void setQueryLogLevelInfo(boolean queryLogLevelInfo) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting queryLogLevelInfo: " + queryLogLevelInfo); } QLog.unlock(); QLog.setQueryLogLevelInfo(queryLogLevelInfo); QLog.lock(); } // =================================================================================== // Execute Status Log Level Info // ============================= public void setExecuteStatusLogLevelInfo(boolean executeStatusLogLevelInfo) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting executeStatusLogLevelInfo: " + executeStatusLogLevelInfo); } XLog.unlock(); XLog.setExecuteStatusLogLevelInfo(executeStatusLogLevelInfo); XLog.lock(); } // =================================================================================== // Log Format // ========== public String getLogDateFormat() { return _logDateFormat; } public void setLogDateFormat(String logDateFormat) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting logDateFormat: " + logDateFormat); } _logDateFormat = logDateFormat; } public String getLogTimestampFormat() { return _logTimestampFormat; } public void setLogTimestampFormat(String logTimestampFormat) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting logTimestampFormat: " + logTimestampFormat); } _logTimestampFormat = logTimestampFormat; } // [DBFlute-0.9.0] // =================================================================================== // DataSource Handler // ================== /** * @return The handler of data source. (Nullable) */ public DataSourceHandler getDataSourceHandler() { return _dataSourceHandler; } /** * @param dataSourceHandler The handler of data source. (Nullable) */ public void setDataSourceHandler(DataSourceHandler dataSourceHandler) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting dataSourceHandler: " + dataSourceHandler); } _dataSourceHandler = dataSourceHandler; } // [DBFlute-0.9.7.6] // =================================================================================== // PhysicalConnection Digger // ========================= /** * @return The digger of physical connection. (NotNull: has a default instance) */ public PhysicalConnectionDigger getPhysicalConnectionDigger() { return _physicalConnectionDigger; } /** * @param physicalConnectionDigger The digger of physical connection. (NotNull) */ public void setPhysicalConnectionDigger(PhysicalConnectionDigger physicalConnectionDigger) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting physicalConnectionDigger: " + physicalConnectionDigger); } if (physicalConnectionDigger == null) { throw new IllegalArgumentException("The argument 'physicalConnectionDigger' should not be null."); } _physicalConnectionDigger = physicalConnectionDigger; } // [DBFlute-0.9.6.4] // =================================================================================== // Sequence Cache // ============== /** * @return The key generator of sequence cache. (Nullable) */ public SequenceCacheKeyGenerator getSequenceCacheKeyGenerator() { return _sequenceCacheKeyGenerator; } /** * @param sequenceCacheKeyGenerator The key generator of sequence cache. (Nullable) */ public void setSequenceCacheKeyGenerator(SequenceCacheKeyGenerator sequenceCacheKeyGenerator) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting sequenceCacheKeyGenerator: " + sequenceCacheKeyGenerator); } _sequenceCacheKeyGenerator = sequenceCacheKeyGenerator; } // [DBFlute-0.9.6.9] // =================================================================================== // SqlClause Creator // ================= /** * @return The creator of SQL clause. (Nullable) */ public SqlClauseCreator getSqlClauseCreator() { return _sqlClauseCreator; } /** * @param sqlClauseCreator The creator of SQL clause. (Nullable) */ public void setSqlClauseCreator(SqlClauseCreator sqlClauseCreator) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting sqlClauseCreator: " + sqlClauseCreator); } _sqlClauseCreator = sqlClauseCreator; } // [DBFlute-0.9.7.6] // =================================================================================== // TableSqlName Filter // =================== /** * @return The SQL name filter for table. (Nullable) */ public SqlNameFilter getTableSqlNameFilter() { return _tableSqlNameFilter; } /** * Set the SQL name filter for table.
* This setting should be called before container's initialization. * (its exact meaning is: before class loading of DBMeta for table) * @param tableSqlNameFilter The SQL name filter for table. (Nullable) */ public void setTableSqlNameFilter(SqlNameFilter tableSqlNameFilter) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting tableSqlNameFilter: " + tableSqlNameFilter); } _tableSqlNameFilter = tableSqlNameFilter; } // =================================================================================== // OutsideSql Package // ================== /** * @return The package of outside SQL. (Nullable) */ public String getOutsideSqlPackage() { return _outsideSqlPackage; } /** * @param outsideSqlPackage The package of outside SQL. (Nullable) */ public void setOutsideSqlPackage(String outsideSqlPackage) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting outsideSqlPackage: " + outsideSqlPackage); } _outsideSqlPackage = outsideSqlPackage; } // [DBFlute-0.9.7.0] // =================================================================================== // OutsideSql Executor // =================== public OutsideSqlExecutorFactory getOutsideSqlExecutorFactory() { return _outsideSqlExecutorFactory; } public void setOutsideSqlExecutorFactory(OutsideSqlExecutorFactory outsideSqlExecutorFactory) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting outsideSqlExecutorFactory: " + outsideSqlExecutorFactory); } _outsideSqlExecutorFactory = outsideSqlExecutorFactory; } // [DBFlute-0.8.2] // =================================================================================== // SQL Log Registry // ================ public boolean isUseSqlLogRegistry() { return _useSqlLogRegistry; } public void setUseSqlLogRegistry(boolean useSqlLogRegistry) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting useSqlLogRegistry: " + useSqlLogRegistry); } _useSqlLogRegistry = useSqlLogRegistry; } // [DBFlute-0.9.0] // =================================================================================== // Select Index // ============ public boolean isDisableSelectIndex() { return _disableSelectIndex; } public void setDisableSelectIndex(boolean disableSelectIndex) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting disableSelectIndex: " + disableSelectIndex); } _disableSelectIndex = disableSelectIndex; } // =================================================================================== // Database Dependency // =================== #if ($database.isAvailableDatabaseDependency()) #if ($database.isDatabasePostgreSQL()) // ----------------------------------------------------- // Full-Text Search Operand // ------------------------ public org.seasar.dbflute.dbway.WayOfPostgreSQL.OperandOfLikeSearch getFullTextSearchOperand() { return _fullTextSearchOperand; } public void useDefaultFullTextSearchOperand() { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Using fullTextSearchOperand: Default"); } _fullTextSearchOperand = org.seasar.dbflute.dbway.WayOfPostgreSQL.OperandOfLikeSearch.FULL_TEXT_SEARCH; } public void useOldFullTextSearchOperand() { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Using fullTextSearchOperand: Old"); } _fullTextSearchOperand = org.seasar.dbflute.dbway.WayOfPostgreSQL.OperandOfLikeSearch.OLD_FULL_TEXT_SEARCH; } #end #end // =================================================================================== // Internal Debug // ============== public boolean isInternalDebug() { return _internalDebug; } public void setInternalDebug(boolean internalDebug) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Setting internalDebug: " + internalDebug); } _internalDebug = internalDebug; } // =================================================================================== // Value Type // ========== /** * Register the basic value type.
* This setting is shared per DBMS in the same class loader. * @param keyType The type as key. (NotNull) * @param valueType The basic value type. (NotNull) */ public void registerBasicValueType(Class keyType, ValueType valueType) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Registering basic valueType: " + keyType + " = " + valueType); } TnValueTypes.registerBasicValueType(currentDBDef(), keyType, valueType); } public void removeBasicValueType(Class keyType) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Removing basic valueType: " + keyType); } TnValueTypes.removeBasicValueType(currentDBDef(), keyType); } /** * Register the plug-in value type.
* This setting is shared per DBMS in the same class loader. * @param keyName The name as key. (NotNull) * @param valueType The plug-in value type. (NotNull) */ public void registerPluginValueType(String keyName, ValueType valueType) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Registering plug-in valueType: " + keyName + " = " + valueType); } TnValueTypes.registerPluginValueType(currentDBDef(), keyName, valueType); } public void removePluginValueType(String keyName) { assertNotLocked(); if (_log.isInfoEnabled()) { _log.info("...Removing plug-in valueType: keyName=" + keyName); } TnValueTypes.removePluginValueType(currentDBDef(), keyName); } // =================================================================================== // Configuration Lock // ================== public boolean isLocked() { return _locked; } public void lock() { if (_log.isInfoEnabled()) { _log.info("...Locking the configuration of DBFlute"); } _locked = true; } public void unlock() { if (_log.isInfoEnabled()) { _log.info("...Unlocking the configuration of DBFlute"); } _locked = false; } protected void assertNotLocked() { if (!isLocked()) { return; } String msg = "The configuration of DBFlute is locked."; throw new IllegalDBFluteConfigAccessException(msg); } // =================================================================================== // Assist Helper // ============= protected DBDef currentDBDef() { return ${glDBCurrent}.getInstance().currentDBDef(); } protected boolean isCurrentDBDef(DBDef currentDBDef) { return ${glDBCurrent}.getInstance().isCurrentDBDef(currentDBDef); } // =================================================================================== // Implemented Class // ================= // ----------------------------------------------------- // Spring // ------ protected static class SpringDBCPDataSourceHandler implements DataSourceHandler { public Connection getConnection(DataSource ds) throws SQLException { final Connection conn = getConnectionFromUtils(ds); if (isConnectionTransactional(conn, ds)) { return new NotClosingConnectionWrapper(conn); } else { return conn; } } public Connection getConnectionFromUtils(DataSource ds) { #if ($database.isTargetContainerSpring()) return DataSourceUtils.getConnection(ds); #else throw new UnsupportedOperationException("This method is only for Spring Framework."); #end } public boolean isConnectionTransactional(Connection conn, DataSource ds) { #if ($database.isTargetContainerSpring()) return DataSourceUtils.isConnectionTransactional(conn, ds); #else throw new UnsupportedOperationException("This method is only for Spring Framework."); #end } @Override public String toString() { return "SpringDBCPDataSourceHandler(for Spring and Commons-DBCP)"; } } // ----------------------------------------------------- // Oracle // ------ public static class ImplementedOracleAgent implements OracleAgent { public Object toOracleDate(Timestamp timestamp) { #if ($database.isAvailableOracleNativeJDBC()) return new oracle.sql.DATE(timestamp); #else throw new UnsupportedOperationException("This method is only for Oracle."); #end } public Object toOracleArray(Connection conn, String arrayTypeName, Object arrayValue) throws SQLException { #if ($database.isAvailableOracleNativeJDBC()) oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor(arrayTypeName, conn); return new oracle.sql.ARRAY(desc, conn, arrayValue); #else throw new UnsupportedOperationException("This method is only for Oracle."); #end } public Object toStandardArray(Object oracleArray) throws SQLException { #if ($database.isAvailableOracleNativeJDBC()) return ((oracle.sql.ARRAY)oracleArray).getArray(); #else throw new UnsupportedOperationException("This method is only for Oracle."); #end } public boolean isOracleArray(Object obj) { #if ($database.isAvailableOracleNativeJDBC()) return obj instanceof oracle.sql.ARRAY; #else throw new UnsupportedOperationException("This method is only for Oracle."); #end } public Object toOracleStruct(Connection conn, String structTypeName, Object[] attrs) throws SQLException { #if ($database.isAvailableOracleNativeJDBC()) oracle.sql.StructDescriptor desc = new oracle.sql.StructDescriptor(structTypeName, conn); return new ImplementedOracleStructWrapper(new oracle.sql.STRUCT(desc, conn, attrs)); #else throw new UnsupportedOperationException("This method is only for Oracle."); #end } public Object[] toStandardStructAttributes(Object oracleStruct) throws SQLException { #if ($database.isAvailableOracleNativeJDBC()) return ((oracle.sql.STRUCT)oracleStruct).getAttributes(); #else throw new UnsupportedOperationException("This method is only for Oracle."); #end } public boolean isOracleStruct(Object obj) { #if ($database.isAvailableOracleNativeJDBC()) return obj instanceof oracle.sql.STRUCT; #else throw new UnsupportedOperationException("This method is only for Oracle."); #end } public PhysicalConnectionDigger getPhysicalConnectionDigger() { return ${glDBFluteConfig}.getInstance().getPhysicalConnectionDigger(); } } #if ($database.isAvailableOracleNativeJDBC()) public static class ImplementedOracleStructWrapper implements oracle.sql.ORAData { protected oracle.sql.STRUCT _struct; public ImplementedOracleStructWrapper(oracle.sql.STRUCT struct) { _struct = struct; } public oracle.sql.Datum toDatum(Connection conn) throws SQLException { return _struct; } } #end public static class ImplementedOracleDateType extends OracleDateType { @Override protected OracleAgent createOracleAgent() { return new ImplementedOracleAgent(); } } public static class ImplementedOracleArrayType extends OracleArrayType { public ImplementedOracleArrayType(String arrayTypeName, Class elementType) { super(arrayTypeName, elementType); } @Override protected OracleAgent createOracleAgent() { return new ImplementedOracleAgent(); } } public static class ImplementedOracleStructType extends OracleStructType { public ImplementedOracleStructType(String structTypeName, Class entityType) { super(structTypeName, entityType); } @Override protected OracleAgent createOracleAgent() { return new ImplementedOracleAgent(); } } // ----------------------------------------------------- // Physical Connection // ------------------- public static class ImplementedPhysicalConnectionDigger implements PhysicalConnectionDigger { public Connection digUp(Connection conn) throws SQLException { if (conn instanceof NotClosingConnectionWrapper) { conn = ((NotClosingConnectionWrapper) conn).getActualConnection(); } conn = resolveS2DBCP(conn); conn = resolveCommonsDBCP(conn); return conn; } protected Connection resolveS2DBCP(Connection conn) { #if ($database.isTargetContainerSeasar()) if (conn instanceof ConnectionWrapper) { conn = ((ConnectionWrapper)conn).getPhysicalConnection(); } #end return conn; } protected Connection resolveCommonsDBCP(Connection conn) { if ("org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper".equals(conn.getClass().getName())) { conn = getFieldConnection(conn, "delegate"); } if ("org.apache.commons.dbcp.PoolableConnection".equals(conn.getClass().getName())) { conn = getFieldConnection(conn, "_conn"); } return conn; } protected Connection getFieldConnection(Connection conn, String fieldName) { Field field = DfReflectionUtil.getWholeField(conn.getClass(), fieldName); return (Connection) DfReflectionUtil.getValueForcedly(field, conn); } } }