001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jdbc.core.metadata; 018 019import javax.sql.DataSource; 020 021import org.apache.commons.logging.Log; 022import org.apache.commons.logging.LogFactory; 023 024import org.springframework.dao.DataAccessResourceFailureException; 025import org.springframework.jdbc.support.JdbcUtils; 026import org.springframework.jdbc.support.MetaDataAccessException; 027 028/** 029 * Factory used to create a {@link TableMetaDataProvider} implementation 030 * based on the type of database being used. 031 * 032 * @author Thomas Risberg 033 * @since 2.5 034 */ 035public final class TableMetaDataProviderFactory { 036 037 private static final Log logger = LogFactory.getLog(TableMetaDataProviderFactory.class); 038 039 040 private TableMetaDataProviderFactory() { 041 } 042 043 044 /** 045 * Create a {@link TableMetaDataProvider} based on the database meta-data. 046 * @param dataSource used to retrieve meta-data 047 * @param context the class that holds configuration and meta-data 048 * @return instance of the TableMetaDataProvider implementation to be used 049 */ 050 public static TableMetaDataProvider createMetaDataProvider(DataSource dataSource, TableMetaDataContext context) { 051 try { 052 return JdbcUtils.extractDatabaseMetaData(dataSource, databaseMetaData -> { 053 String databaseProductName = JdbcUtils.commonDatabaseName(databaseMetaData.getDatabaseProductName()); 054 boolean accessTableColumnMetaData = context.isAccessTableColumnMetaData(); 055 TableMetaDataProvider provider; 056 057 if ("Oracle".equals(databaseProductName)) { 058 provider = new OracleTableMetaDataProvider( 059 databaseMetaData, context.isOverrideIncludeSynonymsDefault()); 060 } 061 else if ("PostgreSQL".equals(databaseProductName)) { 062 provider = new PostgresTableMetaDataProvider(databaseMetaData); 063 } 064 else if ("Apache Derby".equals(databaseProductName)) { 065 provider = new DerbyTableMetaDataProvider(databaseMetaData); 066 } 067 else if ("HSQL Database Engine".equals(databaseProductName)) { 068 provider = new HsqlTableMetaDataProvider(databaseMetaData); 069 } 070 else { 071 provider = new GenericTableMetaDataProvider(databaseMetaData); 072 } 073 074 if (logger.isDebugEnabled()) { 075 logger.debug("Using " + provider.getClass().getSimpleName()); 076 } 077 provider.initializeWithMetaData(databaseMetaData); 078 if (accessTableColumnMetaData) { 079 provider.initializeWithTableColumnMetaData(databaseMetaData, 080 context.getCatalogName(), context.getSchemaName(), context.getTableName()); 081 } 082 return provider; 083 }); 084 } 085 catch (MetaDataAccessException ex) { 086 throw new DataAccessResourceFailureException("Error retrieving database meta-data", ex); 087 } 088 } 089 090}