package org.apache.ddlutils.platform; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ import org.apache.commons.lang3.StringUtils; import org.apache.ddlutils.DdlUtilsException; import org.apache.ddlutils.Platform; import org.apache.ddlutils.PlatformUtils; import org.apache.ddlutils.platform.axion.AxionPlatform; import org.apache.ddlutils.platform.cloudscape.CloudscapePlatform; import org.apache.ddlutils.platform.db2.Db2Platform; import org.apache.ddlutils.platform.db2.Db2v8Platform; import org.apache.ddlutils.platform.derby.DerbyPlatform; import org.apache.ddlutils.platform.firebird.FirebirdPlatform; import org.apache.ddlutils.platform.h2.H2Platform; import org.apache.ddlutils.platform.hsqldb.HsqlDbPlatform; import org.apache.ddlutils.platform.interbase.InterbasePlatform; import org.apache.ddlutils.platform.maxdb.MaxDbPlatform; import org.apache.ddlutils.platform.mckoi.MckoiPlatform; import org.apache.ddlutils.platform.mssql.MSSqlPlatform; import org.apache.ddlutils.platform.mysql.MySql50Platform; import org.apache.ddlutils.platform.mysql.MySqlPlatform; import org.apache.ddlutils.platform.oracle.Oracle10Platform; import org.apache.ddlutils.platform.oracle.Oracle8Platform; import org.apache.ddlutils.platform.oracle.Oracle9Platform; import org.apache.ddlutils.platform.postgresql.PostgreSqlPlatform; import org.apache.ddlutils.platform.sapdb.SapDbPlatform; import org.apache.ddlutils.platform.sqlite.Sqlite3Platform; import org.apache.ddlutils.platform.sybase.SybaseASE15Platform; import org.apache.ddlutils.platform.sybase.SybasePlatform; import org.apache.log4j.Logger; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; /** * A factory of {@link org.apache.ddlutils.Platform} instances based on a case * insensitive database name. Note that this is a convenience class as the platforms * can also simply be created via their constructors. * * @version $Revision: 209952 $ */ public class PlatformFactory { private static Logger logger = Logger.getLogger(PlatformFactory.class); /** The database name -> platform map. */ private static Map _platforms = null; /** * Returns the platform map. * * @return The platform list */ private static synchronized Map getPlatforms() { if (_platforms == null) { // lazy initialization _platforms = new HashMap(); registerPlatforms(); } return _platforms; } /** * Creates a new platform for the given (case insensitive) database name * or returns null if the database is not recognized. * * @param databaseName The name of the database (case is not important) * @return The platform or <code>null</code> if the database is not supported */ public static synchronized Platform createNewPlatformInstance(String databaseName) throws DdlUtilsException { try { Class platformClass = (Class) getPlatforms().get(databaseName.toLowerCase()); return platformClass != null ? (Platform) platformClass.newInstance() : null; } catch (Exception ex) { String message = "Could not create platform for database "+databaseName; logger.error(message); throw new DdlUtilsException(message, ex); } } /** * Creates a new platform for the specified database. This is a shortcut method that uses * {@link PlatformUtils#determineDatabaseType(String, String)} to determine the parameter * for {@link #createNewPlatformInstance(String)}. Note that no database connection is * established when using this method. * * @param jdbcDriver The jdbc driver * @param jdbcConnectionUrl The connection url * @return The platform or <code>null</code> if the database is not supported */ public static synchronized Platform createNewPlatformInstance(String jdbcDriver, String jdbcConnectionUrl) throws DdlUtilsException { if (jdbcDriver==null) { logger.error("Empty jdbcDriver"); } if (jdbcDriver==null) { logger.error("Empty jdbcConnectionUrl"); } return createNewPlatformInstance(new PlatformUtils().determineDatabaseType(jdbcDriver, jdbcConnectionUrl)); } /** * Creates a new platform for the specified database. This is a shortcut method that uses * {@link PlatformUtils#determineDatabaseType(DataSource)} to determine the parameter * for {@link #createNewPlatformInstance(String)}. Note that this method sets the data source * at the returned platform instance (method {@link Platform#setDataSource(DataSource)}). * * @param dataSource The data source for the database * @return The platform or <code>null</code> if the database is not supported */ public static synchronized Platform createNewPlatformInstance(DataSource dataSource) throws DdlUtilsException { Platform platform = createNewPlatformInstance(new PlatformUtils().determineDatabaseType(dataSource)); platform.setDataSource(dataSource); return platform; } /** * Creates a new platform for the specified database. This is a shortcut method that uses * {@link PlatformUtils#determineDatabaseType(DataSource)} to determine the parameter * for {@link #createNewPlatformInstance(String)}. Note that this method sets the data source * at the returned platform instance (method {@link Platform#setDataSource(DataSource)}). * * @param dataSource The data source for the database * @param username The user name to use for connecting to the database * @param password The password to use for connecting to the database * @return The platform or <code>null</code> if the database is not supported */ public static synchronized Platform createNewPlatformInstance(DataSource dataSource, String username, String password) throws DdlUtilsException { if (dataSource==null) { logger.error("Empty dataSource"); } if (StringUtils.isBlank(username)) { logger.warn("Empty username"); } if (StringUtils.isBlank(password)) { logger.warn("Empty password"); } Platform platform = createNewPlatformInstance(new PlatformUtils().determineDatabaseType(dataSource, username, password)); platform.setDataSource(dataSource); platform.setUsername(username); platform.setPassword(password); return platform; } /** * Returns a list of all supported platforms. * * @return The names of the currently registered platforms */ public static synchronized String[] getSupportedPlatforms() { return (String[]) getPlatforms().keySet().toArray(new String[0]); } /** * Determines whether the indicated platform is supported. * * @param platformName The name of the platform * @return <code>true</code> if the platform is supported */ public static boolean isPlatformSupported(String platformName) { return getPlatforms().containsKey(platformName.toLowerCase()); } /** * Registers a new platform. * * @param platformName The platform name * @param platformClass The platform class which must implement the {@link Platform} interface */ public static synchronized void registerPlatform(String platformName, Class platformClass) { addPlatform(getPlatforms(), platformName, platformClass); } /** * Registers the known platforms. */ private static void registerPlatforms() { addPlatform(_platforms, Sqlite3Platform.DATABASENAME, Sqlite3Platform.class); addPlatform(_platforms, AxionPlatform.DATABASENAME, AxionPlatform.class); addPlatform(_platforms, CloudscapePlatform.DATABASENAME, CloudscapePlatform.class); addPlatform(_platforms, Db2Platform.DATABASENAME, Db2Platform.class); addPlatform(_platforms, Db2v8Platform.DATABASENAME, Db2v8Platform.class); addPlatform(_platforms, DerbyPlatform.DATABASENAME, DerbyPlatform.class); addPlatform(_platforms, FirebirdPlatform.DATABASENAME, FirebirdPlatform.class); addPlatform(_platforms, H2Platform.DATABASENAME, H2Platform.class); addPlatform(_platforms, HsqlDbPlatform.DATABASENAME, HsqlDbPlatform.class); addPlatform(_platforms, InterbasePlatform.DATABASENAME, InterbasePlatform.class); addPlatform(_platforms, MaxDbPlatform.DATABASENAME, MaxDbPlatform.class); addPlatform(_platforms, MckoiPlatform.DATABASENAME, MckoiPlatform.class); addPlatform(_platforms, MSSqlPlatform.DATABASENAME, MSSqlPlatform.class); addPlatform(_platforms, MySqlPlatform.DATABASENAME, MySqlPlatform.class); addPlatform(_platforms, MySql50Platform.DATABASENAME, MySql50Platform.class); addPlatform(_platforms, Oracle8Platform.DATABASENAME, Oracle8Platform.class); addPlatform(_platforms, Oracle9Platform.DATABASENAME, Oracle9Platform.class); addPlatform(_platforms, Oracle10Platform.DATABASENAME, Oracle10Platform.class); addPlatform(_platforms, PostgreSqlPlatform.DATABASENAME, PostgreSqlPlatform.class); addPlatform(_platforms, SapDbPlatform.DATABASENAME, SapDbPlatform.class); addPlatform(_platforms, SybasePlatform.DATABASENAME, SybasePlatform.class); addPlatform(_platforms, SybaseASE15Platform.DATABASENAME, SybaseASE15Platform.class); } /** * Registers a new platform. * * @param platformMap The map to add the platform info to * @param platformName The platform name * @param platformClass The platform class which must implement the {@link Platform} interface */ private static synchronized void addPlatform(Map platformMap, String platformName, Class platformClass) { if (!Platform.class.isAssignableFrom(platformClass)) { String message = "Cannot register class "+platformClass.getName() +" because it does not implement the "+Platform.class.getName()+" interface"; logger.error(message); throw new IllegalArgumentException(message); } platformMap.put(platformName.toLowerCase(), platformClass); } }